diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml
new file mode 100644
index 0000000000..02933c1ce8
--- /dev/null
+++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml
@@ -0,0 +1,128 @@
+import QtQuick 2.3
+import "../../../../../shared"
+import "../../../../../imports"
+import "./TransactionComponents"
+
+Rectangle {
+ property string tokenAmount: "100"
+ property string token: "SNT"
+ property string fiatValue: "10 USD"
+ property bool outgoing: true
+ property string state: "addressReceived"
+ property string time: "9:41 AM"
+
+ id: root
+ width: 170
+ height: childrenRect.height
+ radius: 16
+ color: Style.current.background
+ border.color: Style.current.border
+ border.width: 1
+
+ StyledText {
+ id: title
+ color: Style.current.secondaryText
+ text: outgoing ? qsTr("↑ Outgoing transaction") : qsTr("↓ Incoming transaction")
+ font.weight: Font.Medium
+ anchors.top: parent.top
+ anchors.topMargin: Style.current.halfPadding
+ anchors.horizontalCenter: parent.horizontalCenter
+ font.pixelSize: 13
+ }
+
+ Item {
+ id: valueContainer
+ height: tokenText.height + fiatText.height
+ anchors.top: title.bottom
+ anchors.topMargin: 4
+ anchors.right: parent.right
+ anchors.rightMargin: 12
+ anchors.left: parent.left
+ anchors.leftMargin: 12
+
+ Image {
+ id: tokenImage
+ source: `../../../../img/tokens/${root.token}.png`
+ width: 24
+ height: 24
+ anchors.verticalCenter: parent.verticalCenter
+ }
+
+ StyledText {
+ id: tokenText
+ color: Style.current.text
+ text: `${root.tokenAmount} ${root.token}`
+ anchors.left: tokenImage.right
+ anchors.leftMargin: Style.current.halfPadding
+ font.pixelSize: 22
+ }
+
+ StyledText {
+ id: fiatText
+ color: Style.current.secondaryText
+ text: root.fiatValue
+ anchors.top: tokenText.bottom
+ anchors.left: tokenText.left
+ font.pixelSize: 13
+ }
+ }
+
+ Loader {
+ id: bubbleLoader
+ active: root.state !== Constants.addressRequested || !outgoing
+ sourceComponent: stateBubbleComponent
+ anchors.top: valueContainer.bottom
+ anchors.topMargin: Style.current.halfPadding
+ width: parent.width
+ height: item.height + 12
+ }
+
+ Component {
+ id: stateBubbleComponent
+
+ StateBubble {
+ state: root.state
+ }
+ }
+
+ Loader {
+ id: buttonsLoader
+ active: (root.state === Constants.addressRequested && !root.outgoing) ||
+ (root.state === Constants.addressReceived && root.outgoing)
+ sourceComponent: root.outgoing ? signAndSendComponent : acceptTransactionComponent
+ anchors.top: bubbleLoader.active ? bubbleLoader.bottom : valueContainer.bottom
+ anchors.topMargin: bubbleLoader.active ? 0 : Style.current.halfPadding
+ width: parent.width
+ height: item.height
+ }
+
+ Component {
+ id: acceptTransactionComponent
+
+ AcceptTransaction {}
+ }
+
+ Component {
+ id: signAndSendComponent
+
+ SendTransactionButton {}
+ }
+
+ StyledText {
+ id: timeText
+ color: Style.current.secondaryText
+ text: root.time
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 9
+ anchors.right: parent.right
+ anchors.rightMargin: 12
+ font.pixelSize: 10
+ }
+
+}
+
+/*##^##
+Designer {
+ D{i:0;formeditorColor:"#4c4e50";formeditorZoom:1.25}
+}
+##^##*/
diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml
new file mode 100644
index 0000000000..319e898803
--- /dev/null
+++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml
@@ -0,0 +1,70 @@
+import QtQuick 2.3
+import "../../../../../../shared"
+import "../../../../../../imports"
+
+Item {
+ width: parent.width
+ height: childrenRect.height
+
+ Separator {
+ id: separator1
+ }
+
+ StyledText {
+ id: acceptText
+ color: Style.current.blue
+ text: qsTr("Accept and share address")
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.WordWrap
+ font.weight: Font.Medium
+ anchors.right: parent.right
+ anchors.left: parent.left
+ bottomPadding: Style.current.halfPadding
+ topPadding: Style.current.halfPadding
+ anchors.top: separator1.bottom
+ font.pixelSize: 15
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ console.log('Accept')
+ }
+ }
+ }
+
+ Separator {
+ id: separator2
+ anchors.topMargin: 0
+ anchors.top: acceptText.bottom
+ }
+
+ StyledText {
+ id: declineText
+ color: Style.current.blue
+ text: qsTr("Decline")
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.WordWrap
+ font.weight: Font.Medium
+ anchors.right: parent.right
+ anchors.left: parent.left
+ bottomPadding: Style.current.padding
+ topPadding: Style.current.padding
+ anchors.top: separator2.bottom
+ font.pixelSize: 15
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ console.log('Decline')
+ }
+ }
+ }
+}
+
+/*##^##
+Designer {
+ D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.25}
+}
+##^##*/
diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml
new file mode 100644
index 0000000000..9fc39f8f32
--- /dev/null
+++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml
@@ -0,0 +1,42 @@
+import QtQuick 2.3
+import "../../../../../../shared"
+import "../../../../../../imports"
+
+Item {
+ width: parent.width
+ height: childrenRect.height
+
+ Separator {
+ id: separator
+ }
+
+ StyledText {
+ id: signText
+ color: Style.current.blue
+ text: qsTr("Sign and send")
+ horizontalAlignment: Text.AlignHCenter
+ wrapMode: Text.WordWrap
+ font.weight: Font.Medium
+ anchors.right: parent.right
+ anchors.left: parent.left
+ bottomPadding: Style.current.halfPadding
+ topPadding: Style.current.halfPadding
+ anchors.top: separator1.bottom
+ font.pixelSize: 15
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ console.log('Sign')
+ }
+ }
+ }
+}
+
+/*##^##
+Designer {
+ D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.25}
+}
+##^##*/
+
diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml
new file mode 100644
index 0000000000..e0ce7e2737
--- /dev/null
+++ b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml
@@ -0,0 +1,82 @@
+import QtQuick 2.3
+import QtGraphicalEffects 1.13
+import "../../../../../../shared"
+import "../../../../../../imports"
+
+Rectangle {
+ property string state: Constants.pending
+
+ id: root
+ width: childrenRect.width + 12
+ height: childrenRect.height
+ border.width: 1
+ border.color: Style.current.border
+ radius: 24
+
+ SVGImage {
+ id: stateImage
+ source: {
+ switch (root.state) {
+ case Constants.pending:
+ case Constants.addressReceived:
+ case Constants.shared:
+ case Constants.addressRequested: return "../../../../../img/dotsLoadings.svg"
+ case Constants.confirmed: return "../../../../../img/check.svg"
+ case Constants.unknown:
+ case Constants.failure:
+ case Constants.declined: return "../../../../../img/exclamation.svg"
+ default: return ""
+ }
+ }
+ width: 16
+ height: 16
+ anchors.left: parent.left
+ anchors.leftMargin: Style.current.halfPadding
+ anchors.verticalCenter: stateText.verticalCenter
+ }
+
+ ColorOverlay {
+ anchors.fill: stateImage
+ source: stateImage
+ color: state == Constants.confirmed ? Style.current.transparent : Style.current.text
+ }
+
+ StyledText {
+ id: stateText
+ color: {
+ if (root.state === Constants.unknown || root.state === Constants.failure) {
+ return Style.current.danger
+ }
+ if (root.state === Constants.confirmed || root.state === Constants.declined) {
+ return Style.current.text
+ }
+
+ return Style.current.secondaryText
+ }
+ text: {
+ switch (root.state) {
+ case Constants.pending: return qsTr("Pending")
+ case Constants.confirmed: return qsTr("Confirmed")
+ case Constants.unknown: return qsTr("Unknown token")
+ case Constants.addressRequested: return qsTr("Address requested")
+ case Constants.addressReceived: return qsTr("Address received")
+ case Constants.declined: return qsTr("Transaction declined")
+ case Constants.shared: return qsTr("Shared ‘Other Account’")
+ case Constants.failure: return qsTr("Failure")
+ default: return qsTr("Unknown state")
+ }
+ }
+ font.weight: Font.Medium
+ anchors.left: stateImage.right
+ anchors.leftMargin: 4
+ bottomPadding: Style.current.halfPadding
+ topPadding: Style.current.halfPadding
+ font.pixelSize: 13
+ }
+}
+
+/*##^##
+Designer {
+ D{i:0;formeditorColor:"#808080";formeditorZoom:2}
+}
+##^##*/
diff --git a/ui/app/img/dotsLoadings.svg b/ui/app/img/dotsLoadings.svg
new file mode 100644
index 0000000000..f85f1e73cb
--- /dev/null
+++ b/ui/app/img/dotsLoadings.svg
@@ -0,0 +1,5 @@
+
diff --git a/ui/app/img/exclamation.svg b/ui/app/img/exclamation.svg
new file mode 100644
index 0000000000..831f628a69
--- /dev/null
+++ b/ui/app/img/exclamation.svg
@@ -0,0 +1,3 @@
+
diff --git a/ui/imports/Constants.qml b/ui/imports/Constants.qml
index 7d6452b899..2079807462 100644
--- a/ui/imports/Constants.qml
+++ b/ui/imports/Constants.qml
@@ -23,6 +23,16 @@ QtObject {
readonly property string seedWalletType: "seed"
readonly property string generatedWalletType: "generated"
+ // Transaction states
+ readonly property string pending: "pending"
+ readonly property string confirmed: "confirmed"
+ readonly property string unknown: "unknown"
+ readonly property string addressRequested: "addressRequested"
+ readonly property string addressReceived: "addressReceived"
+ readonly property string declined: "declined"
+ readonly property string shared: "shared"
+ readonly property string failure: "failure"
+
readonly property var accountColors: [
"#9B832F",
"#D37EF4",
diff --git a/ui/nim-status-client.pro b/ui/nim-status-client.pro
index ac98932625..e90da0d97a 100644
--- a/ui/nim-status-client.pro
+++ b/ui/nim-status-client.pro
@@ -133,6 +133,10 @@ DISTFILES += \
app/AppLayouts/Chat/ChatColumn/MessageComponents/RectangleCorner.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/SentMessage.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/Sticker.qml \
+ app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml \
+ app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml \
+ app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml \
+ app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/UserImage.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/UsernameLabel.qml \
app/AppLayouts/Chat/ChatColumn/MessageComponents/qmldir \