//
// Copyright 2025 Circle Internet Group, Inc. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation
import CYBAVOWallet

@objc(RNWallets)
class RNWallets: NSObject {
    var domain = Bundle.main.bundleIdentifier ?? ""

    @objc public func getMarketInfos(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getMarketInfos(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e.marketInfos)
                let newdict: [String: Any] = [
                    "marketInfos": dict,
                ]
                resolve(newdict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getCurrencies(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getCurrencies(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e.currencies)
                let newdict: [String: Any] = [
                    "currencies": dict,
                ]
                resolve(newdict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getWalletsByChainIds(_ chainIds: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        let chainIdArr = chainIds as! [Int64]
        Wallets.shared.getWalletsByChainIds(chainIds: chainIdArr){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toCustomDict(result: e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getWalletsByCaip2ChainIds(_ caip2ChainIds: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
     let caip2ChainIdArr = caip2ChainIds as! [String]
      Wallets.shared.getWalletsByCaip2ChainIds(caip2ChainIds: caip2ChainIdArr){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toCustomDict(result: e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getWallets(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getWallets(){ result in
            switch(result) {
            case .success(let e):
                let wallets = RNWalletSDK.toDict(e.wallets)
                let dict: [String: Any] = [
                    "wallets": wallets,
                ]
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getWalletLegacy(_ walletId: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getWalletLegacy(walletId: Int64(walletId)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                if var newDict = dict as? [String:Any] {
                    newDict["wallet_name"] = newDict["name"]
                    resolve(newDict)
                } else {
                    resolve(dict)
                }
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getWallet(_ walletId: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getWallet(walletId: Int64(walletId)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e.wallet)
                if let dict = dict as? [String:Any] {
                    let newDict: [String: Any] = [
                        "wallet": dict["some"],
                    ]
                    resolve(newDict)
                } else {
                    resolve(dict)
                }
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getSolNftTokens(_ walletId: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getSolNftTokens(walletId: Int64(walletId)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e.tokens)
                let newdict: [String: Any] = [
                    "tokens": dict,
                ]
                resolve(newdict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func createWalletWithPinSecret(_ currency: Int, withTokenAddress tokenAddress: String, withParent parentWalletId: NSInteger, withName name: String, byPinSecret: NSDictionary, withExtras extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var walletExtras = [String:String]()
        for (key, value) in extras {
            if let key = key as? String, let value = value as? String {
                walletExtras[key] = value
            }
        }
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.createWallet(currency: currency, tokenAddress: tokenAddress, parentWalletId: Int64(parentWalletId), name: name, pinSecret: pinSecret, extras: walletExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func createWallet(_ currency: Int, withTokenAddress tokenAddress: String, withParent parentWalletId: NSInteger, withName name: String, withPinCode pinCode: String, withExtras extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var walletExtras = [String:String]()
        for (key, value) in extras {
            if let key = key as? String, let value = value as? String {
                walletExtras[key] = value
            }
        }
        Wallets.shared.createWallet(currency: currency, tokenAddress: tokenAddress, parentWalletId: Int64(parentWalletId), name: name, pinCode: pinCode, extras: walletExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func renameWallet(_ walletId: NSInteger, withName name: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.renameWallet(walletId: Int64(walletId), name: name){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getWalletUsage(_ walletId: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getWalletUsage(walletId: Int64(walletId)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func createTransactionWithSecureToken(_ fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }
        Wallets.shared.createTransaction(fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func createTransactionSmsWithSecureToken(_ actionToken: String, smsCode: String, fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }
        Wallets.shared.createTransactionSms(actionToken:actionToken, smsCode:smsCode,fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func createTransactionBioWithSecureToken(_ promptMessage: String, fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }
        Wallets.shared.createTransactionBio(promptMessage:promptMessage,fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }


    @objc public func createTransactionWithPinSecret(_ fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, byPinSecret: NSDictionary, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                extras[key] = value
            }
        }
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.createTransaction(fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description, pinSecret: pinSecret, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func createTransactionSmsWithPinSecret(_ actionToken: String, smsCode: String, fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, byPinSecret: NSDictionary, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                extras[key] = value
            }
        }
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.createTransactionSms(actionToken:actionToken, smsCode:smsCode, fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description, pinSecret: pinSecret, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func createTransactionBioWithPinSecret(_ promptMessage: String, fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, byPinSecret: NSDictionary, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                extras[key] = value
            }
        }
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.createTransactionBio(promptMessage:promptMessage, fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description, pinSecret: pinSecret, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }


    @objc public func createTransactionSmsWithPinCode(_ actionToken: String, smsCode: String, fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, byPIN pinCode: String, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                extras[key] = value
            }
        }

        Wallets.shared.createTransactionSms(actionToken:actionToken, smsCode:smsCode, fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description, pinCode: pinCode, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func createTransactionBioWithPinCode(_ promptMessage: String, fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, byPIN pinCode: String, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                extras[key] = value
            }
        }
        Wallets.shared.createTransactionBio(promptMessage:promptMessage, fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description,pinCode: pinCode, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }


    @objc public func createTransactionWithPinCode(_ fromWalletId: NSInteger, toAddress addr: String, withAmount amount: String, withFee transactionFee: String, withDesc description: String, byPIN pinCode: String, extras inputs: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                extras[key] = value
            }
        }
        Wallets.shared.createTransaction(fromWalletId: Int64(fromWalletId), toAddress: addr, amount: amount, transactionFee: transactionFee, description: description, pinCode: pinCode, extras: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func increaseTransactionFeeWithPinSecret(_ fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.increaseTransactionFee(fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }


    @objc public func increaseTransactionFeeSmsWithPinSecret(_ actionToken: String, smsCode: String, fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.increaseTransactionFeeSms(actionToken:actionToken, smsCode:smsCode, fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func increaseTransactionFeeBioWithPinSecret(_ promptMessage: String, fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.increaseTransactionFeeBio(promptMessage:promptMessage, fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func increaseTransactionFeeSmsWithPinCode(_ actionToken: String, smsCode: String, fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.increaseTransactionFeeSms(actionToken:actionToken, smsCode:smsCode, fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func increaseTransactionFeeBioWithPinCode(_ promptMessage: String, fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.increaseTransactionFeeBio(promptMessage:promptMessage, fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func increaseTransactionFeeWithPinCode(_ fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.increaseTransactionFee(fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }


    @objc public func cancelTransactionWithPinSecret(_ fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.cancelTransaction(fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelTransactionSmsWithPinSecret(_ actionToken: String, smsCode: String, fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.cancelTransactionSms(actionToken:actionToken, smsCode:smsCode, fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelTransactionBioWithPinSecret(_  promptMessage: String, fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.cancelTransactionBio(promptMessage: promptMessage, fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelTransactionSmsWithPinCode(_ actionToken: String, smsCode: String, fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.cancelTransactionSms(actionToken:actionToken, smsCode:smsCode, fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelTransactionBioWithPinCode(_  promptMessage: String, fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.cancelTransactionBio(promptMessage: promptMessage, fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelTransactionWithPinCode(_ fromWalletId: NSInteger, txid txid: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.cancelTransaction(fromWalletId: Int64(fromWalletId), txid: txid, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func requestSecureToken(_ pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
        Wallets.shared.requestSecureToken(pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func requestSecureTokenWithPinSecret(_ byPinSecret: NSDictionary,resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.requestSecureToken(pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func requestSecureTokenSmsWithPinSecret(_ actionToken: String, smsCode: String, byPinSecret: NSDictionary,resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.requestSecureTokenSms(actionToken:actionToken, smsCode:smsCode, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func requestSecureTokenBioWithPinSecret(_ promptMessage: String, byPinSecret: NSDictionary,resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.requestSecureTokenBio(promptMessage:promptMessage, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }
    @objc public func requestSecureTokenSmsWithPinCode(_ actionToken: String, smsCode: String, byPIN pinCode: String,resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
        Wallets.shared.requestSecureTokenSms(actionToken:actionToken, smsCode:smsCode, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func requestSecureTokenBioWithPinCode(_ promptMessage: String, byPIN pinCode: String,resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
        Wallets.shared.requestSecureTokenBio(promptMessage:promptMessage, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func clearSecureToken(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
        Wallets.shared.clearSecureToken(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getTransactionFee(_ currency: NSInteger, withTokenAddress tokenAddress: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getTransactionFee(currency: currency, tokenAddress: tokenAddress){ result in
            switch(result) {
            case .success(let e):
                let obj: [String: Any] = [
                    "low": [
                        "amount": e.low.amount,
                        "description": e.low.description,
                    ],
                    "medium": [
                        "amount": e.medium.amount,
                        "description": e.medium.description,
                    ],
                    "high": [
                        "amount": e.high.amount,
                        "description": e.high.description,
                    ],
                    "withdrawMin": e.withdrawMin
                ]
                resolve(obj)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    private func getBalancesAddressesMap(addresses: NSArray) -> [Int64:BalanceAddress]{
        var queryAddresses = [Int64:BalanceAddress]()
        var index: Int64 = 0
        for addr in addresses {
            if let addrMap = addr as? NSMutableDictionary {
                if let currency = addrMap["currency"] as? Int, let tokenAddress = addrMap["tokenAddress"] as? String, let address = addrMap["address"] as? String {
                    let v = RNBalanceAddress()
                    v.currency = Int(currency)
                    v.tokenAddress = tokenAddress
                    v.address = address
                    queryAddresses[index] = v
                    index = index + 1
                }
            }
        }
        return queryAddresses
    }
    private func getBalanceResultFromResp(result: GetBalanceResult) -> [String:Any]{
            var allBalances = [String:Any]()
            for (index, addr) in result.balance {
                var dict: [String:Any] = [
                    "balance": addr.balance,
                    "tokenBalance": addr.tokenBalance,
                    "unconfirmedBalance": addr.unconfirmedBalance,
                    "tokens": addr.tokens
                ]

                var array: [[String:Any]] = []
                for tokenIdAmount in addr.tokenIdAmounts {
                    let d: [String:Any] = ["tokenId":tokenIdAmount.tokenId, "amount": tokenIdAmount.amount]
                    array.append(d)
                }
                dict["tokenIdAmounts"] = array
                allBalances[String(index)] = dict
            }
        return allBalances
    }
    @objc public func getBalances(_ addresses: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        let queryAddresses = getBalancesAddressesMap(addresses: addresses)
        Wallets.shared.getBalances(addresses: queryAddresses){ result in
            switch(result) {
            case .success(let e):
                let allBalances = self.getBalanceResultFromResp(result: e)
                resolve(allBalances)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }
    @objc public func getBalancesLegacy(_ addresses: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        let queryAddresses = getBalancesAddressesMap(addresses: addresses)
        Wallets.shared.getBalancesLegacy(addresses: queryAddresses){ result in
            switch(result) {
            case .success(let e):
                let allBalances = self.getBalanceResultFromResp(result: e)
                resolve(allBalances)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getFinancialProducts(_ kinds: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
     let kindArr = kinds as! [Int]
        Wallets.shared.getFinancialProducts(kinds: kindArr){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getFinancialHistoryByKind(_ kind: NSInteger, page: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){

        Wallets.shared.getFinancialHistory(kind: Int(kind), page: page){ result in
            switch(result) {
            case .success(let e):
                var dict : [String: Any] = [:]
                var productDict : [String: Any] = [:]
                for (key, p) in e.products {
                    productDict[key] = RNWalletSDK.toDict(p)
                }
                dict["kind"] = e.kind.rawValue
                dict["prevPage"] = e.prevPage
                dict["nextPage"] = e.nextPage
                dict["products"] = productDict
                dict["histories"] = RNWalletSDK.toDict(e.history)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getFinancialHistoryByProduct(_ productUuid: String, page: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){

        Wallets.shared.getFinancialHistory(productUuid: productUuid, page: page){ result in
            switch(result) {
            case .success(let e):
                var dict : [String: Any] = [:]
                var productDict : [String: Any] = [:]
                for (key, p) in e.products {
                    productDict[key] = RNWalletSDK.toDict(p)
                }
                dict["kind"] = e.kind.rawValue
                dict["prevPage"] = e.prevPage
                dict["nextPage"] = e.nextPage
                dict["products"] = productDict
                dict["histories"] = RNWalletSDK.toDict(e.history)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getFinancialBonusList(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getFinancialBonusList(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getFinancialOrder(_ productUuid: String, orderId: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){

        Wallets.shared.getFinancialOrder(productUuid: productUuid, orderId: orderId){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getHistory(_ currency: NSInteger, withTokenAddress tokenAddress: String, address walletAddress: String, from start: NSInteger, with count: NSInteger, byFilter filter: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in filter {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                if key == "direction" {
                    let v = value as! Int
                    switch v {
                        case Direction.OUT.rawValue:
                            extras["direction"] = Direction.OUT
                            break;
                        case Direction.IN.rawValue:
                            extras["direction"] = Direction.IN
                            break;
                        default: break;
                    }
                }else{
                    extras[key] = value
                }
            }
        }
        Wallets.shared.getHistory(currency: Int(currency), tokenAddress: tokenAddress, walletAddress: walletAddress, start: Int(start), count: Int(count), filters: extras){ result in
            switch(result) {
            case .success(let e):
                resolve(self.getHistroyResultDict(e: e))
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }
    private func getHistroyResultDict(e: GetHistoryResult) -> [String: Any]{
            var array: [Any] = []
            for item in e.transactions{
                let tDict = RNWalletSDK.toDict(item)
                if var tDict = tDict as? [String:Any] {
                    tDict["currency"] = item.currency
                    tDict["tokenAddress"] = item.tokenAddress
                    tDict["type"] = item.type.rawValue
                    tDict.removeValue(forKey: "r_info")
                    array.append(tDict)
                }
            }
            let newDict: [String: Any] = [
                "start": e.start,
                "total": e.total,
                "transactions": array,
            ]
        return newDict
    }
    @objc public func getUserHistory(_ start: NSInteger, with count: NSInteger, byFilter filter: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in filter {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                if key == "type" {
                    if let v = value as? Int{
                        extras["type"] = TransactionType.getType(value:v)
                    }else if let nsArr = value as? NSArray{
                        var newArr = [TransactionType]()
                        for e in nsArr {
                            if let i = e as? Int{
                                newArr.append(TransactionType.getType(value:i))
                            }
                        }
                        extras["type"] = newArr
                    }
                }else{
                    extras[key] = value
                }
            }
        }
        Wallets.shared.getUserHistory(start: Int(start), count: Int(count), filters: extras){ result in
            switch(result) {
            case .success(let e):
                resolve(self.getHistroyResultDict(e: e))
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getHistoryWithCrossChain(_ currency: NSInteger, withTokenAddress tokenAddress: String, address walletAddress: String, from start: NSInteger, with count: NSInteger, crossChain crossChain: NSInteger, byFilter filter: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in filter {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                if key == "direction" {
                    let v = value as! Int
                    switch v {
                        case Direction.OUT.rawValue:
                            extras["direction"] = Direction.OUT
                            break;
                        case Direction.IN.rawValue:
                            extras["direction"] = Direction.IN
                            break;
                        default: break;
                    }
                }else{
                    extras[key] = value
                }
            }
        }
        Wallets.shared.getHistory(currency: Int(currency), tokenAddress: tokenAddress, walletAddress: walletAddress, start: Int(start), count: Int(count),
                                  crosschain: Int(crossChain), filters: extras){ result in
            switch(result) {
            case .success(let e):
                resolve(self.getHistroyResultDict(e: e))
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionRead(_ walletId: NSInteger, name: String, contractAddress: String, abiJson: String, args: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [Any](arrayLiteral: args.count)
        for arg in args {
            if let nsArr = arg as? NSArray{
                var newArr = [Any](arrayLiteral: nsArr.count)
                for e in nsArr {
                    newArr.append(e)
                }
                extras.append(newArr)
            }else{
                extras.append(arg)
            }
        }
        Wallets.shared.callAbiFunctionRead(walletId: Int64(walletId), name: name, contractAddress: contractAddress, abiJson: abiJson, args: extras){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionTransactionWithPinSecret(_ walletId: NSInteger, name: String, contractAddress: String, abiJson: String, args: NSArray, transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }

        var extras = [Any](arrayLiteral: args.count)
        for arg in args {
            if let nsArr = arg as? NSArray{
                var newArr = [Any](arrayLiteral: nsArr.count)
                for e in nsArr {
                    newArr.append(e)
                }
                extras.append(newArr)
            }else{
                extras.append(arg)
            }
        }
        Wallets.shared.callAbiFunctionTransaction(walletId: Int64(walletId), name: name, contractAddress: contractAddress, abiJson: abiJson, args: extras, transactionFee: transactionFee, pinSecret: pinSecret){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionTransactionSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, name: String, contractAddress: String, abiJson: String, args: NSArray, transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }

        var extras = [Any](arrayLiteral: args.count)
        for arg in args {
            if let nsArr = arg as? NSArray{
                var newArr = [Any](arrayLiteral: nsArr.count)
                for e in nsArr {
                    newArr.append(e)
                }
                extras.append(newArr)
            }else{
                extras.append(arg)
            }
        }
        Wallets.shared.callAbiFunctionTransactionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), name: name, contractAddress: contractAddress, abiJson: abiJson, args: extras, transactionFee: transactionFee, pinSecret: pinSecret){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionTransactionBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, name: String, contractAddress: String, abiJson: String, args: NSArray, transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }

        var extras = [Any](arrayLiteral: args.count)
        for arg in args {
            if let nsArr = arg as? NSArray{
                var newArr = [Any](arrayLiteral: nsArr.count)
                for e in nsArr {
                    newArr.append(e)
                }
                extras.append(newArr)
            }else{
                extras.append(arg)
            }
        }
        Wallets.shared.callAbiFunctionTransactionBio(promptMessage:promptMessage, walletId: Int64(walletId), name: name, contractAddress: contractAddress, abiJson: abiJson, args: extras, transactionFee: transactionFee, pinSecret: pinSecret){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionTransactionSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, name: String, contractAddress: String, abiJson: String, args: NSArray, transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [Any](arrayLiteral: args.count)
        for arg in args {
            if let nsArr = arg as? NSArray{
                var newArr = [Any](arrayLiteral: nsArr.count)
                for e in nsArr {
                    newArr.append(e)
                }
                extras.append(newArr)
            }else{
                extras.append(arg)
            }
        }
        Wallets.shared.callAbiFunctionTransactionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), name: name, contractAddress: contractAddress, abiJson: abiJson, args: extras, transactionFee: transactionFee, pinCode: pinCode){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionTransactionBioWithPinCode(_ promptMessage: String, walletId: NSInteger, name: String, contractAddress: String, abiJson: String, args: NSArray, transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [Any](arrayLiteral: args.count)
        for arg in args {
            if let nsArr = arg as? NSArray{
                var newArr = [Any](arrayLiteral: nsArr.count)
                for e in nsArr {
                    newArr.append(e)
                }
                extras.append(newArr)
            }else{
                extras.append(arg)
            }
        }
        Wallets.shared.callAbiFunctionTransactionBio(promptMessage:promptMessage, walletId: Int64(walletId), name: name, contractAddress: contractAddress, abiJson: abiJson, args: extras, transactionFee: transactionFee, pinCode: pinCode){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }




    @objc public func callAbiFunctionTransaction(_ walletId: NSInteger, name: String, contractAddress: String, abiJson: String, args: NSArray,transactionFee: String, byPinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [Any](arrayLiteral: args.count)
        for arg in args {
            if let nsArr = arg as? NSArray{
                var newArr = [Any](arrayLiteral: nsArr.count)
                for e in nsArr {
                    newArr.append(e)
                }
                extras.append(newArr)
            }else{
                extras.append(arg)
            }
        }
        Wallets.shared.callAbiFunctionTransaction(walletId: Int64(walletId), name: name, contractAddress: contractAddress, abiJson: abiJson, args: extras, transactionFee: transactionFee, pinCode: byPinCode){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunction(_ walletId: NSInteger, function name: String, with inputs: NSDictionary, by pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }

        Wallets.shared.callAbiFunction(walletId: Int64(walletId), name: name, inputs: extras, pinCode: pinCode){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionWithPinSecret(_ walletId: NSInteger, function name: String, with inputs: NSDictionary, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }

        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }

        Wallets.shared.callAbiFunction(walletId: Int64(walletId), name: name, inputs: extras, pinSecret: pinSecret){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, function name: String, with inputs: NSDictionary, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }

        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }

        Wallets.shared.callAbiFunctionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), name: name, inputs: extras, pinSecret: pinSecret){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, function name: String, with inputs: NSDictionary, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }

        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }

        Wallets.shared.callAbiFunctionBio(promptMessage:promptMessage, walletId: Int64(walletId), name: name, inputs: extras, pinSecret: pinSecret){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, function name: String, with inputs: NSDictionary, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }

        Wallets.shared.callAbiFunctionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), name: name, inputs: extras, pinCode: pinCode){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func callAbiFunctionBioWithPinCode(_ promptMessage: String, walletId: NSInteger, function name: String, with inputs: NSDictionary, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in inputs {
            if let key = key as? String {
                extras[key] = value
            }
        }

        Wallets.shared.callAbiFunctionBio(promptMessage:promptMessage, walletId: Int64(walletId), name: name, inputs: extras, pinCode: pinCode){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }
    @objc public func getTransactionInfo(_ currency: NSInteger, with txid: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getTransactionInfo(currency: currency, txid: txid){result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func validateEosAccount(_ accountName: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getEosAccountValid(accountName: accountName){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getEosRamPrice(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getEosRamPrice(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getEosResourceState(_ accountName: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getEosResourceState(accountName: accountName){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getTransactionsInfo(_ currency: NSInteger, txids inputs: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var txids = [String]()
        for v in inputs {
            if let v = v as? String {
                txids.append(v)
            }
        }
        Wallets.shared.getTransactionsInfo(currency: Int64(currency), txids: txids){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func signRawTx(_ walletId: NSInteger, rawTx rawTx: String, pinCode pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.signRawTx(walletId: Int64(walletId), rawTx: rawTx, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }


    @objc public func commonSignRawTx(_ walletId: NSInteger, rawTx rawTx: String, pinCode pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.commonSignRawTx(walletId: Int64(walletId), rawTx: rawTx, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func signRawTxWithPinSecret(_ walletId: NSInteger, rawTx rawTx: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.signRawTx(walletId: Int64(walletId), rawTx: rawTx, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func commonSignRawTxWithPinSecret(_ walletId: NSInteger, rawTx rawTx: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.commonSignRawTx(walletId: Int64(walletId), rawTx: rawTx, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func signRawTxSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, rawTx rawTx: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.signRawTxSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), rawTx: rawTx, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func commonSignRawTxSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, rawTx rawTx: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.commonSignRawTxSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), rawTx: rawTx, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func signRawTxSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, rawTx rawTx: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.signRawTxSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), rawTx: rawTx, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func commonSignRawTxSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, rawTx rawTx: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.commonSignRawTxSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), rawTx: rawTx, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func signRawTxBioWithPinCode(_ promptMessage: String, walletId: NSInteger, rawTx rawTx: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.signRawTxBio(promptMessage:promptMessage, walletId: Int64(walletId), rawTx: rawTx, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func commonSignRawTxBioWithPinCode(_ promptMessage: String, walletId: NSInteger, rawTx rawTx: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.commonSignRawTxBio(promptMessage:promptMessage, walletId: Int64(walletId), rawTx: rawTx, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func signRawTxBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, rawTx rawTx: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.signRawTxBio(promptMessage:promptMessage, walletId: Int64(walletId), rawTx: rawTx, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func commonSignRawTxBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, rawTx rawTx: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.commonSignRawTxBio(promptMessage:promptMessage, walletId: Int64(walletId), rawTx: rawTx, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func setSolTokenAccountTransaction(_ walletId: NSInteger, pinCode pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.setSolTokenAccountTransaction(walletId: Int64(walletId), pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func setSolTokenAccountTransactionWithPinSecret(_ walletId: NSInteger, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.setSolTokenAccountTransaction(walletId: Int64(walletId), pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func setSolTokenAccountTransactionSms(_ actionToken: String, smsCode: String, walletId: NSInteger, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.setSolTokenAccountTransactionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func setSolTokenAccountTransactionSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.setSolTokenAccountTransactionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func setSolTokenAccountTransactionBio(_ promptMessage: String, walletId: NSInteger, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.setSolTokenAccountTransactionBio(promptMessage:promptMessage, walletId: Int64(walletId), pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func setSolTokenAccountTransactionBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.setSolTokenAccountTransactionBio(promptMessage:promptMessage, walletId: Int64(walletId), pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func sendSignedTx(_ walletId: NSInteger, signedTx signedTx: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.sendSignedTx(walletId: Int64(walletId), signedTx: signedTx){ result in
                switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func estimateTransaction(_ currency: NSInteger, tokenAddress tokenAddress: String, amount amount: String, transactionFee transactionFee: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.estimateTransaction(currency: Int(currency), tokenAddress: tokenAddress, amount: amount, transactionFee: transactionFee){ result in
                switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func estimateTransactionWithId(_ currency: NSInteger, tokenAddress tokenAddress: String, amount amount: String, transactionFee transactionFee: String, walletId: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.estimateTransaction(currency: Int(currency), tokenAddress: tokenAddress, amount: amount, transactionFee: transactionFee, walletId: Int64(walletId)){ result in
                switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func estimateTransactionWithIdAddress(_ currency: NSInteger, tokenAddress tokenAddress: String, amount amount: String, transactionFee transactionFee: String, walletId: NSInteger, toAddress toAddress: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.estimateTransaction(currency: Int(currency), tokenAddress: tokenAddress, amount: amount, transactionFee: transactionFee, walletId: Int64(walletId), toAddress: tokenAddress){ result in
                switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func exportPrivateKey(_ walletId: NSInteger, pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.exportPrivateKey(walletId: Int64(walletId), pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func signMessage(_ walletId: NSInteger, message: String, pinCode: String, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        Wallets.shared.signMessage(walletId: Int64(walletId), message: message, pinCode: pinCode, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func signMessageWithPinSecret(_ walletId: NSInteger, message: String, byPinSecret: NSDictionary, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.signMessage(walletId: Int64(walletId), message: message, pinSecret: pinSecret, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func signMessageSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, message: String, byPinSecret: NSDictionary, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.signMessageSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), message: message, pinSecret: pinSecret, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func signMessageBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, message: String, byPinSecret: NSDictionary, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.signMessageBio(promptMessage:promptMessage, walletId: Int64(walletId), message: message, pinSecret: pinSecret, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func signMessageSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, message: String, byPIN pinCode: String, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        Wallets.shared.signMessageSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), message: message, pinCode: pinCode, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func signMessageBioWithPinCode(_ promptMessage: String, walletId: NSInteger, message: String, byPIN pinCode: String, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        Wallets.shared.signMessageBio(promptMessage:promptMessage, walletId: Int64(walletId), message: message, pinCode: pinCode, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func getCurrencyPrices(_ wallets: NSArray, exchangeCurrencies: NSArray, approximateRates: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        let ws = wallets as! [[String : Any]]
        let es = exchangeCurrencies as! [String]
        var dictExtras = [String: [String: Double]]()
                for (key, value) in approximateRates {
                    if value is NSNull {
                        continue
                    }
                    if let key = key as? String, let value = value as? [String: Double] {
                        dictExtras[key] = value
                    }
                }
        Wallets.shared.getCurrencyPrices(wallets: ws ,exchangeCurrencies: es, approximateRates: dictExtras){ result in
                switch(result) {
                case .success(let e):
                    resolve(e)
                case .failure(let error):
                    let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                    reject(String(error.code.rawValue), error.message, e)
                }
            }
     }

    @objc public func queryCoinType(_ address: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.queryCoinType(address: address){ result in
                switch(result) {
                case .success(let e):
                let dict = RNWalletSDK.toDict(e.coinItems)
                let newdict: [String: Any] = [
                    "coinItems": dict,
                ]
                resolve(newdict)
                case .failure(let error):
                    let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                    reject(String(error.code.rawValue), error.message, e)
                }
            }
     }

    @objc public func walletConnectSignTypedData(_ walletId: NSInteger, typedData typedData: String, pinCode pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.walletConnectSignTypedData(walletId: Int64(walletId), typedData: typedData, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func walletConnectSignTypedDataWithPinSecret(_ walletId: NSInteger, typedData typedData: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.walletConnectSignTypedData(walletId: Int64(walletId), typedData: typedData, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func walletConnectSignTypedDataSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, typedData typedData: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.walletConnectSignTypedDataSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), typedData: typedData, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func walletConnectSignTypedDataBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, typedData typedData: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.walletConnectSignTypedDataBio(promptMessage:promptMessage, walletId: Int64(walletId), typedData: typedData, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func walletConnectSignTypedDataSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, typedData typedData: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){

            Wallets.shared.walletConnectSignTypedDataSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), typedData: typedData, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func walletConnectSignTypedDataBioWithPinCode(_ promptMessage: String, walletId: NSInteger, typedData typedData: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){

            Wallets.shared.walletConnectSignTypedDataBio(promptMessage:promptMessage, walletId: Int64(walletId), typedData: typedData, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func walletConnectSignTransaction(_ walletId: NSInteger, signParams signParams: String, pinCode pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.walletConnectSignTransaction(walletId: Int64(walletId), signParams: signParams, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func walletConnectSignTransactionWithPinSecret(_ walletId: NSInteger, signParams signParams: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.walletConnectSignTransaction(walletId: Int64(walletId), signParams: signParams, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

    @objc public func walletConnectSignTransactionSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, signParams signParams: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
                reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
                return
            }
            Wallets.shared.walletConnectSignTransactionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), signParams: signParams, pinSecret: pinSecret){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

   @objc public func walletConnectSignTransactionBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, signParams signParams: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
           guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
               reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
               return
           }
           Wallets.shared.walletConnectSignTransactionBio(promptMessage:promptMessage, walletId: Int64(walletId), signParams: signParams, pinSecret: pinSecret){ result in
                   switch(result) {
                   case .success(let e):
                       let dict = RNWalletSDK.toCustomDict(result: e)
                       resolve(dict)
                   case .failure(let error):
                       let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                       reject(String(error.code.rawValue), error.name, e)
                   }
               }
    }

    @objc public func walletConnectSignTransactionSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, signParams signParams: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.walletConnectSignTransactionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), signParams: signParams, pinCode: pinCode){ result in
                    switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toCustomDict(result: e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
                    }
                }
     }

   @objc public func walletConnectSignTransactionBioWithPinCode(_ promptMessage: String, walletId: NSInteger, signParams signParams: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
           Wallets.shared.walletConnectSignTransactionBio(promptMessage:promptMessage, walletId: Int64(walletId), signParams: signParams, pinCode: pinCode){ result in
                   switch(result) {
                   case .success(let e):
                       let dict = RNWalletSDK.toCustomDict(result: e)
                       resolve(dict)
                   case .failure(let error):
                       let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                       reject(String(error.code.rawValue), error.name, e)
                   }
               }
    }

    @objc public func walletConnectSignMessage(_ walletId: NSInteger, message: String, pinCode: String, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        Wallets.shared.walletConnectSignMessage(walletId: Int64(walletId), message: message, pinCode: pinCode, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func walletConnectSignMessageWithPinSecret(_ walletId: NSInteger, message: String, byPinSecret: NSDictionary, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.walletConnectSignMessage(walletId: Int64(walletId), message: message, pinSecret: pinSecret, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func walletConnectSignMessageSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, message: String, byPinSecret: NSDictionary, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.walletConnectSignMessageSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), message: message, pinSecret: pinSecret, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func walletConnectSignMessageBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, message: String, byPinSecret: NSDictionary, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.walletConnectSignMessageBio(promptMessage:promptMessage, walletId: Int64(walletId), message: message, pinSecret: pinSecret, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func walletConnectSignMessageSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, message: String, byPIN pinCode: String, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        Wallets.shared.walletConnectSignMessageSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), message: message, pinCode: pinCode, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func walletConnectSignMessageBioWithPinCode(_ promptMessage: String, walletId: NSInteger, message: String, byPIN pinCode: String, extras: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var dictExtras = [String:Any]()
        for (key, value) in extras {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                dictExtras[key] = value
            }
        }

        Wallets.shared.walletConnectSignMessageBio(promptMessage:promptMessage, walletId: Int64(walletId), message: message, pinCode: pinCode, extras: dictExtras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func walletConnectSendSignedTransaction(_ walletId: NSInteger, signedTx signedTx: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.walletConnectSendSignedTransaction(walletId: Int64(walletId), signedTx: signedTx){ result in
                switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func getWalletConnectSignedTx(_ walletId: NSInteger, accessId accessId: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getWalletConnectSignedTx(walletId: Int64(walletId), accessId: accessId){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getWalletConnectUnsignedData(_ walletId: NSInteger, accessId accessId: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getWalletConnectUnsignedData(walletId: Int64(walletId), accessId: accessId){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getWalletConnectApiHistory(_ walletId: NSInteger, from start: NSInteger, with count: NSInteger, byFilter filter: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        var extras = [String:Any]()
        for (key, value) in filter {
            if value is NSNull {
                continue
            }
            if let key = key as? String {
                if key == "direction" {
                    let v = value as! Int
                    switch v {
                        case Direction.OUT.rawValue:
                            extras["direction"] = Direction.OUT
                            break;
                        case Direction.IN.rawValue:
                            extras["direction"] = Direction.IN
                            break;
                        default: break;
                    }
                }else{
                    extras[key] = value
                }
            }
        }
        Wallets.shared.getWalletConnectApiHistory(walletId: Int64(walletId), start: Int(start), count: Int(count), filters: extras){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDictHasNil(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func walletConnectSync(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.walletConnectSync(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getNonce(_ walletId: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getNonce(walletId: Int64(walletId)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func registerTokenIds(_ walletId: NSInteger, tokenIds: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        let tokenIdsArr = tokenIds as! [String]
        Wallets.shared.registerTokenIds(walletId: Int64(walletId), tokenIds: tokenIdsArr){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }
    @objc public func cancelWalletConnectTransactionWithPinSecret(_ walletId: NSInteger, accessId accessId: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.cancelWalletConnectTransaction(walletId: Int64(walletId), accessId: accessId, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelWalletConnectTransactionSmsWithPinSecret(_ actionToken: String, smsCode: String, walletId: NSInteger, accessId accessId: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.cancelWalletConnectTransactionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), accessId: accessId, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelWalletConnectTransactionBioWithPinSecret(_ promptMessage: String, walletId: NSInteger, accessId accessId: String, withFee transactionFee: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.cancelWalletConnectTransactionBio(promptMessage:promptMessage, walletId: Int64(walletId), accessId: accessId, transactionFee: transactionFee, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelWalletConnectTransactionSmsWithPinCode(_ actionToken: String, smsCode: String, walletId: NSInteger, accessId accessId: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){

        Wallets.shared.cancelWalletConnectTransactionSms(actionToken:actionToken, smsCode:smsCode, walletId: Int64(walletId), accessId: accessId, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelWalletConnectTransactionBioWithPinCode(_ promptMessage: String, walletId: NSInteger, accessId accessId: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){

        Wallets.shared.cancelWalletConnectTransactionBio(promptMessage:promptMessage, walletId: Int64(walletId), accessId: accessId, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func cancelWalletConnectTransactionWithPinCode(_ walletId: NSInteger, accessId accessId: String, withFee transactionFee: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.cancelWalletConnectTransaction(walletId: Int64(walletId), accessId: accessId, transactionFee: transactionFee, pinCode: pinCode){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func updateDeviceInfoWithType(_ type: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.updateDeviceInfo(type: Int(type)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func updateDeviceInfo(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.updateDeviceInfo(type: nil){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getTransactionSmsCode(_ duration: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getTransactionSmsCode(duration: Int64(duration)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getLoginSmsCode(_ duration: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getLoginSmsCode(duration: Int64(duration)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getSmsCode(_ type: NSInteger, duration: NSInteger, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getSmsCode(otpType: Int(type), duration: Int64(duration)){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func registerPubkey(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.registerPubkey(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getBiometricsType(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        let type = Wallets.shared.getBiometricsType()
        let newdict: [String: Any] = [
            "biometricsType": type.rawValue,
        ]
        resolve(newdict)
    }

    @objc public func isBioKeyExist(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        let exist = Wallets.shared.isBioKeyExist()
        let newdict: [String: Any] = [
            "exist": exist,
        ]
        resolve(newdict)
    }

    @objc public func getSignedActionToken(_ promptMessage: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.getSignedActionToken(promptMessage: promptMessage){ result in
                switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func getActionToken(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getActionToken(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getSignMessageActionToken(_ message: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
            Wallets.shared.getSignMessageActionToken(message: message){ result in
                switch(result) {
                    case .success(let e):
                        let dict = RNWalletSDK.toDict(e)
                        resolve(dict)
                    case .failure(let error):
                        let e = NSError(domain: error.message, code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                        reject(String(error.code.rawValue), error.name, e)
            }
        }
    }

    @objc public func addContractCurrencyWithPinSecret(_ currency: NSInteger, contractAddress: String, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
            reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
            return
        }
        Wallets.shared.addContractCurrency(currency: Int64(currency), contractAddress: contractAddress, pinSecret: pinSecret){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

   @objc public func addContractCurrenciesWithPinSecret(_ currency: NSArray, contractAddress: NSArray, byPinSecret: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
       guard let pinSecret = PinSecretBridge.fromDictionary(dict: byPinSecret) else{
           reject("0", "PinSecret not found", NSError(domain: "", code: 0, userInfo: nil))
           return
       }
    let currencyArr = currency as! [Int64]
    let contractAddressArr = contractAddress as! [String]
       Wallets.shared.addContractCurrencies(currency: currencyArr, contractAddress: contractAddressArr, pinSecret: pinSecret){ result in
           switch(result) {
           case .success(let e):
               let dict = RNWalletSDK.toDict(e)
               resolve(dict)
           case .failure(let error):
               let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
               reject(String(error.code.rawValue), error.message, e)
           }
       }
   }

   @objc public func addContractCurrency(_ currency: NSInteger, contractAddress: String, byPIN pinCode: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
       Wallets.shared.addContractCurrency(currency: Int64(currency), contractAddress: contractAddress, pinCode: pinCode){ result in
           switch(result) {
           case .success(let e):
               let dict = RNWalletSDK.toDict(e)
               resolve(dict)
           case .failure(let error):
               let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
               reject(String(error.code.rawValue), error.message, e)
           }
       }
   }

  @objc public func getMultipleTokenUri(_ currency: NSInteger, tokenAddresses: NSArray, tokenIds: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
   let tokenAddressArr = tokenAddresses as! [String]
   let tokenIdArr = tokenIds as! [String]
    Wallets.shared.getMultipleTokenUri(currency: currency, tokenAddresses: tokenAddressArr, tokenIds: tokenIdArr){ result in
          switch(result) {
          case .success(let e):
            var dict : [String: Any] = [:]
            for (key, info) in e.tokenUriMap {
                dict[key] = RNWalletSDK.toDict(info)
            }
            let newdict: [String: Any] = [
                "tokenUriMap": dict
            ]
            resolve(newdict)
          case .failure(let error):
              let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
              reject(String(error.code.rawValue), error.message, e)
          }
      }
  }

    @objc public func getCurrencyTraits(_ currency: NSInteger, tokenAddress: String, tokenVersion: NSInteger, walletAddress:String,  resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getCurrencyTraits(currency: currency, tokenAddress: tokenAddress, tokenVersion: tokenVersion, walletAddress: walletAddress){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getEstimateGas(_ walletId: NSInteger, content: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getEstimateGas(walletId: Int64(walletId), content: content){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

    @objc public func getSameCurrencyWalletLimit(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
        Wallets.shared.getSameCurrencyWalletLimit(){ result in
            switch(result) {
            case .success(let e):
                let dict = RNWalletSDK.toDict(e)
                resolve(dict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }

   @objc public func getAddressesTags(_ currency: NSInteger, addresses: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
    let addressesArr = addresses as! [String]
     Wallets.shared.getAddressesTags(currency: currency, addresses: addressesArr){ result in
           switch(result) {
           case .success(let e):
             var dict : [String: Any] = [:]
             for (key, info) in e.addressTagMap {
                 dict[key] = RNWalletSDK.toDict(info)
             }
             let newdict: [String: Any] = [
                 "addressTagMap": dict
             ]
             resolve(newdict)
           case .failure(let error):
               let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
               reject(String(error.code.rawValue), error.message, e)
           }
       }
   }

    @objc public func walletConnectGetSupportedChain(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock){
      Wallets.shared.walletConnectGetSupportedChain(){ result in
            switch(result) {
            case .success(let e):
                var dict : [String: Any] = [:]
                for (key, info) in e.chainMap {
                    dict[key] = RNWalletSDK.toDict(info)
                }
                let newdict: [String: Any] = [
                    "chainMap": dict
                ]
                resolve(newdict)
            case .failure(let error):
                let e = NSError(domain: "", code: error.code.rawValue, userInfo: RNWalletSDK.toErrorUserInfo(error))
                reject(String(error.code.rawValue), error.message, e)
            }
        }
    }
}

extension RNWallets {
    @objc static func requiresMainQueueSetup() -> Bool {
        return true
    }
    @objc func constantsToExport() -> [AnyHashable : Any]! {
        var constants = [AnyHashable : Any]()
        //Wallet
        var walletType = [String : Any]()
        for type in WalletType.allCases {
            walletType[type.name] = type.rawValue
        }
        var wallet = [String : Any]()
        wallet["Type"] = walletType
        constants["Wallet"] = wallet

        constants["Transaction"] = getTransactionEnumMap()

        //EosResourceTransactionType
        var eosResourceTransactionType = [String : Any]()
        for type in EosResourceTransactionType.allCases {
            eosResourceTransactionType[type.name] = type.rawValue
        }
        constants["EosResourceTransactionType"] = eosResourceTransactionType

        //ApiHistoryItem.Status
        var status = [String : Any]()
        for dir in Status.allCases {
            status[dir.name] = dir.rawValue
        }

        var apiHistoryItem = [String : Any]()
        apiHistoryItem["Status"] = status
        constants["ApiHistoryItem"] = apiHistoryItem

        var otpType = [String : Any]()
        for type in OtpType.allCases {
            otpType[type.name] = type.rawValue
        }
        constants["OtpType"] = otpType

        var biometryType = [String : Any]()
        for type in BiometryType.allCases {
            biometryType[type.name] = type.rawValue
        }
        constants["BiometricsType"] = biometryType

        var tokenStandard = [String : Any]()
        for type in TokenStandard.allCases {
            tokenStandard[type.name] = type.rawValue
        }
        constants["TokenStandard"] = tokenStandard
        constants["FinancialProduct"] = getFinancialProductEnumMap()
        constants["FinancialHistory"] = getFinancialHistoryEnumMap()
        constants["FinancialBonus"] = getFinancialBonusEnumMap()
        constants["TransactionExplain"] = getTransactionExplainEnumMap()
        return constants
    }
    func getTransactionEnumMap() -> [String : Any]{
        var l21 = [String : Any]()
        for e in Direction.allCases {
            l21[e.name] = e.rawValue
        }
        var l22 = [String : Any]()
        for e in TransactionType.allCases {
            l22[e.name] = e.rawValue
        }

        var l1 = [String : Any]()
        l1["Direction"] = l21
        l1["Type"] = l22
        return l1
    }
    func getFinancialProductEnumMap() -> [String : Any]{
        var l21 = [String : Any]()
        for e in FinancialProductKind.allCases {
            l21[e.name] = e.rawValue
        }
        var l22 = [String : Any]()
        for e in FinancialProductListKind.allCases {
            l22[e.name] = e.rawValue
        }

        var l1 = [String : Any]()
        l1["Kind"] = l21
        l1["ListKind"] = l22
        return l1
    }

    func getFinancialHistoryEnumMap() -> [String : Any]{
        var l21 = [String : Any]()
        for e in FinancialHistoryStatus.allCases {
            l21[e.name] = e.rawValue
        }
        var l22 = [String : Any]()
        for e in FinancialHistoryListKind.allCases {
            l22[e.name] = e.rawValue
        }

        var l1 = [String : Any]()
        l1["Status"] = l21
        l1["ListKind"] = l22
        return l1
    }

    func getFinancialBonusEnumMap() -> [String : Any]{
        var l21 = [String : Any]()
        for e in FinancialBonusKind.allCases {
            l21[e.name] = e.rawValue
        }

        var l1 = [String : Any]()
        l1["Kind"] = l21
        return l1
    }

    func getTransactionExplainEnumMap() -> [String : Any]{
        var l21 = [String : Any]()
        for e in TransactionExplainKind.allCases {
            l21[e.name] = e.rawValue
        }

        var l1 = [String : Any]()
        l1["Kind"] = l21
        return l1
    }
}

