diff --git a/libpurple/account.h b/libpurple/account.h
--- a/libpurple/account.h
+++ b/libpurple/account.h
@@ -643,6 +643,19 @@
 const char *purple_account_get_protocol_id(PurpleAccount *account);
 
 /**
+ * purple_account_get_protocol:
+ * @account: The #PurpleAccount instance.
+ *
+ * Gets the #PurpleProtocol instance for @account.
+ *
+ * Returns: (transfer none): The #PurpleProtocol for @account or %NULL if it
+ *          could not be found.
+ *
+ * Since: 3.0.0
+ */
+PurpleProtocol *purple_account_get_protocol(PurpleAccount *account);
+
+/**
  * purple_account_get_protocol_name:
  * @account: The account.
  *
diff --git a/libpurple/account.c b/libpurple/account.c
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -33,6 +33,7 @@
 #include "purplecredentialmanager.h"
 #include "purpleprivate.h"
 #include "purpleprotocolclient.h"
+#include "purpleprotocolmanager.h"
 #include "purpleprotocolserver.h"
 #include "request.h"
 #include "server.h"
@@ -2057,6 +2058,19 @@
 	return priv->protocol_id;
 }
 
+PurpleProtocol *
+purple_account_get_protocol(PurpleAccount *account) {
+	PurpleAccountPrivate *priv = NULL;
+	PurpleProtocolManager *manager = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
+
+	priv = purple_account_get_instance_private(account);
+	manager = purple_protocol_manager_get_default();
+
+	return purple_protocol_manager_find(manager, priv->protocol_id);
+}
+
 const char *
 purple_account_get_protocol_name(PurpleAccount *account)
 {
diff --git a/libpurple/purpleprotocolmanager.c b/libpurple/purpleprotocolmanager.c
--- a/libpurple/purpleprotocolmanager.c
+++ b/libpurple/purpleprotocolmanager.c
@@ -205,7 +205,7 @@
 	PurpleProtocolManagerPrivate *priv = NULL;
 	gpointer value = NULL;
 
-	g_return_val_if_fail(PURPLE_PROTOCOL_MANAGER(manager), NULL);
+	g_return_val_if_fail(PURPLE_IS_PROTOCOL_MANAGER(manager), NULL);
 	g_return_val_if_fail(id != NULL, NULL);
 
 	priv = purple_protocol_manager_get_instance_private(manager);
diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c
--- a/pidgin/gtkaccount.c
+++ b/pidgin/gtkaccount.c
@@ -2146,7 +2146,7 @@
 	if ((pixbuf != NULL) && purple_account_is_disconnected(account))
 		gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
 
-	protocol = purple_protocols_find(purple_account_get_protocol_id(account));
+	protocol = purple_account_get_protocol(account);
 	if (protocol != NULL)
 		icon_spec = purple_protocol_get_icon_spec(protocol);
 
@@ -2599,11 +2599,7 @@
 static void
 authorize_reason_cb(struct auth_request *ar)
 {
-	const char *protocol_id;
-	PurpleProtocol *protocol = NULL;
-
-	protocol_id = purple_account_get_protocol_id(ar->account);
-	protocol = purple_protocols_find(protocol_id);
+	PurpleProtocol *protocol = purple_account_get_protocol(ar->account);
 
 	if (protocol && (purple_protocol_get_options(protocol) & OPT_PROTO_AUTHORIZATION_GRANTED_MESSAGE)) {
 		/* Duplicate information because ar is freed by closing minidialog */
@@ -2642,11 +2638,7 @@
 static void
 deny_reason_cb(struct auth_request *ar)
 {
-	const char *protocol_id;
-	PurpleProtocol *protocol = NULL;
-
-	protocol_id = purple_account_get_protocol_id(ar->account);
-	protocol = purple_protocols_find(protocol_id);
+	PurpleProtocol *protocol = purple_account_get_protocol(ar->account);
 
 	if (protocol && (purple_protocol_get_options(protocol) & OPT_PROTO_AUTHORIZATION_DENIED_MESSAGE)) {
 		/* Duplicate information because ar is freed by closing minidialog */
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -375,7 +375,7 @@
 	char *chat_name = NULL;
 
 	account = purple_chat_get_account(chat);
-	protocol = purple_protocols_find(purple_account_get_protocol_id(account));
+	protocol = purple_account_get_protocol(account);
 
 	components = purple_chat_get_components(chat);
 
@@ -732,7 +732,7 @@
 		PurpleProtocol *protocol = NULL;
 		type = PURPLE_LOG_CHAT;
 		account = purple_chat_get_account(c);
-		protocol = purple_protocols_find(purple_account_get_protocol_id(account));
+		protocol = purple_account_get_protocol(account);
 		if (protocol) {
 			name = purple_protocol_chat_get_name(PURPLE_PROTOCOL_CHAT(protocol),
 			                                     purple_chat_get_components(c));
@@ -898,8 +898,7 @@
 	PidginAddBuddyData *data = user_data;
 	const char *text;
 
-	protocol = purple_protocols_find(purple_account_get_protocol_id(
-		data->rq_data.account));
+	protocol = purple_account_get_protocol(data->rq_data.account);
 	text = gtk_entry_get_text(GTK_ENTRY(entry));
 
 	gtk_dialog_set_response_sensitive(GTK_DIALOG(data->rq_data.window),
@@ -1981,16 +1980,18 @@
 	/* Double middle click gets info */
 	} else if ((event->button == GDK_BUTTON_MIDDLE) && (event->type == GDK_2BUTTON_PRESS) &&
 			   ((PURPLE_IS_CONTACT(node)) || (PURPLE_IS_BUDDY(node)))) {
+		PurpleAccount *account;
 		PurpleBuddy *b;
 		if(PURPLE_IS_CONTACT(node))
 			b = purple_contact_get_priority_buddy((PurpleContact*)node);
 		else
 			b = (PurpleBuddy *)node;
 
-		protocol = purple_protocols_find(purple_account_get_protocol_id(purple_buddy_get_account(b)));
+		account = purple_buddy_get_account(b);
+		protocol = purple_account_get_protocol(account);
 
 		if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, get_info))
-			pidgin_retrieve_user_info(purple_account_get_connection(purple_buddy_get_account(b)), purple_buddy_get_name(b));
+			pidgin_retrieve_user_info(purple_account_get_connection(account), purple_buddy_get_name(b));
 		handled = TRUE;
 	}
 
@@ -3261,6 +3262,7 @@
 
 	if (PURPLE_IS_CHAT(node))
 	{
+		PurpleAccount *account;
 		PurpleChat *chat;
 		GList *connections;
 		GList *cur = NULL;
@@ -3270,12 +3272,13 @@
 		PidginBlistNode *bnode = g_object_get_data(G_OBJECT(node), UI_DATA);
 
 		chat = (PurpleChat *)node;
-		protocol = purple_protocols_find(purple_account_get_protocol_id(purple_chat_get_account(chat)));
+		account = purple_chat_get_account(chat);
+		protocol = purple_account_get_protocol(account);
 
 		connections = purple_connections_get_all();
 		if (connections && connections->next)
 		{
-			tmp = g_markup_escape_text(purple_account_get_username(purple_chat_get_account(chat)), -1);
+			tmp = g_markup_escape_text(purple_account_get_username(account), -1);
 			g_string_append_printf(str, _("<b>Account:</b> %s"), tmp);
 			g_free(tmp);
 		}
@@ -3292,7 +3295,7 @@
 			}
 
 			conv = purple_conversations_find_chat_with_account(chat_name,
-					purple_chat_get_account(chat));
+			                                                   account);
 			g_free(chat_name);
 		}
 
@@ -3310,7 +3313,7 @@
 
 		if(protocol) {
 			cur = purple_protocol_chat_info(PURPLE_PROTOCOL_CHAT(protocol),
-			                                purple_account_get_connection(purple_chat_get_account(chat)));
+			                                purple_account_get_connection(account));
 		}
 
 		while (cur != NULL)
@@ -3340,6 +3343,7 @@
 		/* NOTE: THIS FUNCTION IS NO LONGER CALLED FOR CONTACTS.
 		 * It is only called by create_tip_for_node(), and create_tip_for_node() is never called for a contact.
 		 */
+		PurpleAccount *account;
 		PurpleContact *c;
 		PurpleBuddy *b;
 		PurplePresence *presence;
@@ -3360,7 +3364,8 @@
 			c = purple_buddy_get_contact(b);
 		}
 
-		protocol = purple_protocols_find(purple_account_get_protocol_id(purple_buddy_get_account(b)));
+		account = purple_buddy_get_account(b);
+		protocol = purple_account_get_protocol(account);
 
 		presence = purple_buddy_get_presence(b);
 		user_info = purple_notify_user_info_new();
@@ -3370,7 +3375,7 @@
 		if (full && connections && connections->next)
 		{
 			purple_notify_user_info_add_pair_plaintext(user_info, _("Account"),
-					purple_account_get_username(purple_buddy_get_account(b)));
+					purple_account_get_username(account));
 		}
 
 		/* Alias */
@@ -3476,9 +3481,7 @@
 			purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), _("Offline"));
 		}
 
-		if (purple_account_is_connected(purple_buddy_get_account(b)) &&
-				protocol)
-		{
+		if (purple_account_is_connected(account) && protocol) {
 			/* Additional text from the protocol */
 			purple_protocol_client_tooltip_text(PURPLE_PROTOCOL_CLIENT(protocol), b, user_info, full);
 		}
@@ -3565,6 +3568,7 @@
 GdkPixbuf *
 pidgin_blist_get_emblem(PurpleBlistNode *node)
 {
+	PurpleAccount *account;
 	PurpleBuddy *buddy = NULL;
 	PidginBlistNode *gtknode = g_object_get_data(G_OBJECT(node), UI_DATA);
 	PurpleProtocol *protocol;
@@ -3602,7 +3606,8 @@
 
 	g_return_val_if_fail(buddy != NULL, NULL);
 
-	if (!purple_account_privacy_check(purple_buddy_get_account(buddy), purple_buddy_get_name(buddy))) {
+	account = purple_buddy_get_account(buddy);
+	if (!purple_account_privacy_check(account, purple_buddy_get_name(buddy))) {
 		path = g_build_filename(PURPLE_DATADIR, "pidgin", "icons",
 			"hicolor", "16x16", "emblems", "emblem-blocked.png",
 			NULL);
@@ -3644,7 +3649,7 @@
 		return _pidgin_blist_get_cached_emblem(path);
 	}
 
-	protocol = purple_protocols_find(purple_account_get_protocol_id(purple_buddy_get_account(buddy)));
+	protocol = purple_account_get_protocol(account);
 	if (!protocol)
 		return NULL;
 
@@ -3712,7 +3717,7 @@
 		else
 			account = purple_chat_get_account(chat);
 
-		protocol = purple_protocols_find(purple_account_get_protocol_id(account));
+		protocol = purple_account_get_protocol(account);
 		if(!protocol)
 			return NULL;
 	}
@@ -3824,12 +3829,13 @@
 
 	/* Name is all that is needed */
 	if (!aliased || biglist) {
+		PurpleAccount *account = purple_buddy_get_account(b);
 
 		/* Status Info */
-		protocol = purple_protocols_find(purple_account_get_protocol_id(purple_buddy_get_account(b)));
+		protocol = purple_account_get_protocol(account);
 
 		if (protocol && PURPLE_PROTOCOL_IMPLEMENTS(protocol, CLIENT, status_text) &&
-				purple_account_get_connection(purple_buddy_get_account(b))) {
+				purple_account_get_connection(account)) {
 			char *tmp = purple_protocol_client_status_text(PURPLE_PROTOCOL_CLIENT(protocol), b);
 			const char *end;
 
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -2496,8 +2496,7 @@
 		if ((chat == NULL) && (gtkconv->history != NULL)) {
 			GHashTable *components;
 			PurpleAccount *account = purple_conversation_get_account(conv);
-			PurpleProtocol *protocol =
-					purple_protocols_find(purple_account_get_protocol_id(account));
+			PurpleProtocol *protocol = purple_account_get_protocol(account);
 			if (purple_account_get_connection(account) != NULL &&
 					PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT, info_defaults)) {
 				components = purple_protocol_chat_info_defaults(PURPLE_PROTOCOL_CHAT(protocol), purple_account_get_connection(account),
diff --git a/pidgin/gtkdialogs.c b/pidgin/gtkdialogs.c
--- a/pidgin/gtkdialogs.c
+++ b/pidgin/gtkdialogs.c
@@ -271,7 +271,7 @@
 	gboolean valid = FALSE;
 
 	account = purple_request_fields_get_account(fields, "account");
-	protocol = purple_protocols_find(purple_account_get_protocol_id(account));
+	protocol = purple_account_get_protocol(account);
 	username = purple_request_fields_get_string(fields, "screenname");
 
 	if (username) {
diff --git a/pidgin/gtkutils.c b/pidgin/gtkutils.c
--- a/pidgin/gtkutils.c
+++ b/pidgin/gtkutils.c
@@ -474,8 +474,7 @@
 				{
 					account = (PurpleAccount *)l->data;
 
-					proto = purple_protocols_find(
-						purple_account_get_protocol_id(account));
+					proto =purple_account_get_protocol(account);
 
 					if (proto == NULL)
 					{
@@ -969,7 +968,7 @@
 
 	g_return_val_if_fail(account != NULL, NULL);
 
-	protocol = purple_protocols_find(purple_account_get_protocol_id(account));
+	protocol = purple_account_get_protocol(account);
 	if (protocol == NULL)
 		return NULL;
 	return pidgin_create_icon_from_protocol(protocol, size, account);
diff --git a/pidgin/pidginapplication.c b/pidgin/pidginapplication.c
--- a/pidgin/pidginapplication.c
+++ b/pidgin/pidginapplication.c
@@ -391,12 +391,10 @@
 pidgin_application_signed_on_cb(PurpleAccount *account, gpointer data) {
 	PidginApplication *application = PIDGIN_APPLICATION(data);
 	PurpleProtocol *protocol = NULL;
-	const gchar *protocol_id = NULL;
 	gboolean should_enable_chat = FALSE, should_enable_room_list = FALSE;
 	gint n_actions = 0;
 
-	protocol_id = purple_account_get_protocol_id(account);
-	protocol = purple_protocols_find(protocol_id);
+	protocol = purple_account_get_protocol(account);
 
 	/* We assume that the current state is correct, so we don't bother changing
 	 * state unless the newly connected account implements the chat interface,
diff --git a/pidgin/pidginlog.c b/pidgin/pidginlog.c
--- a/pidgin/pidginlog.c
+++ b/pidgin/pidginlog.c
@@ -854,7 +854,7 @@
 	for(accounts = purple_accounts_get_all(); accounts != NULL; accounts = accounts->next) {
 
 		PurpleAccount *account = (PurpleAccount *)accounts->data;
-		if(purple_protocols_find(purple_account_get_protocol_id(account)) == NULL)
+		if(purple_account_get_protocol(account) == NULL)
 			continue;
 
 		logs = g_list_concat(purple_log_get_system_logs(account), logs);
