Listening to payments (real-time) on your Stellar wallet

Stellar is an open source, decentralized protocol for digital currency to fiat money low-cost transfers which allows cross-border payments between any pair of currencies.

A Stellar wallet is a digital wallet used to hold lumens & other assets as a digital currency. It consits of a public key and a secret key which in combination can work as an address to recieve and send funds from.

Why do we want to get notified of the latest payments incoming to our wallet

Lets say you have a service whereby you are utilizing stellar as one of your payment options. Inorder to confirm the status of a transfer you need to continously check the whether you have recieved your funds via Horizon.

We need to find a way to get notified of incoming payments.

Solution 1

Periodically retrieve an account’s payments using an API request. By using the following GET request a user is able to retrieve payments related to the account_id/public_key.

Using a curl request:

curl "https://horizon.stellar.org/accounts/<account_id>/payments?limit="

The above curl request gets the latest payments on specified account_id.

An example response is:

{
"_links": {
"self": {
"href": "https://horizon.stellar.org/accounts/GCNL55IJTH2HX26HLNIGYD2JIQLTBAQL3SVPNZA6PXK7NAVHU423WOTE/payments?cursor=\u0026limit=10\u0026order=desc"
},
"next": {
"href": "https://horizon.stellar.org/accounts/GCNL55IJTH2HX26HLNIGYD2JIQLTBAQL3SVPNZA6PXK7NAVHU423WOTE/payments?cursor=110694007436259329\u0026limit=10\u0026order=desc"
},
"prev": {
"href": "https://horizon.stellar.org/accounts/GCNL55IJTH2HX26HLNIGYD2JIQLTBAQL3SVPNZA6PXK7NAVHU423WOTE/payments?cursor=119400713599217665\u0026limit=10\u0026order=asc"
}
},
"_embedded": {
"records": [
{
"_links": {
"self": {
"href": "https://horizon.stellar.org/operations/119400713599217665"
},
"transaction": {
"href": "https://horizon.stellar.org/transactions/b9d7c534b5fa168570a5bffe0f2089de150d00bf8cbd19ec93e897c565958f3f"
},
"effects": {
"href": "https://horizon.stellar.org/operations/119400713599217665/effects"
},
"succeeds": {
"href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=119400713599217665"
},
"precedes": {
"href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=119400713599217665"
}
},
"id": "119400713599217665",
"paging_token": "119400713599217665",
"transaction_successful": true,
"source_account": "GCNL55IJTH2HX26HLNIGYD2JIQLTBAQL3SVPNZA6PXK7NAVHU423WOTE",
"type": "payment",
"type_i": 1,
"created_at": "2020-01-17T20:32:38Z",
"transaction_hash": "b9d7c534b5fa168570a5bffe0f2089de150d00bf8cbd19ec93e897c565958f3f",
"asset_type": "credit_alphanum4",
"asset_code": "USD",
"asset_issuer": "GDUKMGUGDZQK6YHYA5Z6AY2G4XDSZPSZ3SW5UN3ARVMO6QSRDWP5YLEX",
"from": "GCNL55IJTH2HX26HLNIGYD2JIQLTBAQL3SVPNZA6PXK7NAVHU423WOTE",
"to": "GASWJWFRYE55KC7MGANZMMRBK5NPXT3HMPDQ6SEXZN6ZPWYXVVYBFRTE",
"amount": "84.9410878"
},
{
"_links": {
"self": {
"href": "https://horizon.stellar.org/operations/117356420835532801"
},
"transaction": {
"href": "https://horizon.stellar.org/transactions/c25dd84798076ee8ea126c78407d61c7e8f3efdf8739274f56b07a7029500b00"
},
"effects": {
"href": "https://horizon.stellar.org/operations/117356420835532801/effects"
},
"succeeds": {
"href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=117356420835532801"
},
"precedes": {
"href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=117356420835532801"
}
},
"id": "117356420835532801",
"paging_token": "117356420835532801",
"transaction_successful": true,
"source_account": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53",
"type": "payment",
"type_i": 1,
"created_at": "2019-12-18T08:23:35Z",
"transaction_hash": "c25dd84798076ee8ea126c78407d61c7e8f3efdf8739274f56b07a7029500b00",
"asset_type": "native",
"from": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53",
"to": "GCNL55IJTH2HX26HLNIGYD2JIQLTBAQL3SVPNZA6PXK7NAVHU423WOTE",
"amount": "355.3887598"
},
{
"_links": {
"self": {
"href": "https://horizon.stellar.org/operations/115354197276323841"
},
"transaction": {
"href": "https://horizon.stellar.org/transactions/c09d4cee993d60d73c80f036666966738a26b8f3b25d7275b93fd995505b5e5b"
},
"effects": {
"href": "https://horizon.stellar.org/operations/115354197276323841/effects"
},
"succeeds": {
"href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=115354197276323841"
},
"precedes": {
"href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=115354197276323841"
}
},
"id": "115354197276323841",
"paging_token": "115354197276323841",
"transaction_successful": true,
"source_account": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53",
"type": "payment",
"type_i": 1,
"created_at": "2019-11-18T19:59:40Z",
"transaction_hash": "c09d4cee993d60d73c80f036666966738a26b8f3b25d7275b93fd995505b5e5b",
"asset_type": "native",
"from": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53",
"to": "GCNL55IJTH2HX26HLNIGYD2JIQLTBAQL3SVPNZA6PXK7NAVHU423WOTE",
"amount": "688.4065454"
}
]
}
}

Disadvantages of this approach are:

  • The load on servers will increase exponentially as the number of users and transactions increase in the system. This means for each user in your system there must be a job to fetch the latest transactions after every defined duration of time.
  • You also run a risk of overloading the stellar netowrk with multiple requests.

Solution 2

As the heading of the article suggests the second solution involves listening to transactions as they happen. To make this happen we utilize the Stellar SDK which provides an event-stream that can be subscribed to inorder to recieve latest payment information regarding the users account.

The following is how this solution can be imoplemented:

First we install the required stellar-sdk dependency into our project by using the follwoing command:

yarn add stellar-sdk

Secondly we import the stellar-sdk using the require keyword. Thereafter we initialize the server sdk using the horizon url before using it.

var StellarSdk = require("stellar-sdk");
var server = new StellarSdk.Server("https://horizon.stellar.org");

server
.payments()
.cursor('now')
.stream({
onmessage: (payment)=>{},
onerror: (error)=>{}
})

Example result(s) coming from the event stream are as follows:

{
"_links": {
"self": {
"href": "https://horizon.stellar.org/operations/115354197276323841"
},
"transaction": {
"href": "https://horizon.stellar.org/transactions/c09d4cee993d60d73c80f036666966738a26b8f3b25d7275b93fd995505b5e5b"
},
"effects": {
"href": "https://horizon.stellar.org/operations/115354197276323841/effects"
},
"succeeds": {
"href": "https://horizon.stellar.org/effects?order=desc\u0026cursor=115354197276323841"
},
"precedes": {
"href": "https://horizon.stellar.org/effects?order=asc\u0026cursor=115354197276323841"
}
},
"id": "115354197276323841",
"paging_token": "115354197276323841",
"transaction_successful": true,
"source_account": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53",
"type": "payment",
"type_i": 1,
"created_at": "2019-11-18T19:59:40Z",
"transaction_hash": "c09d4cee993d60d73c80f036666966738a26b8f3b25d7275b93fd995505b5e5b",
"asset_type": "native",
"from": "GDV4KECLSZLKRVH4ZTWVAS4I3W2LPAPV66ADFFUZKGIVOTK6GMKGJT53",
"to": "GCNL55IJTH2HX26HLNIGYD2JIQLTBAQL3SVPNZA6PXK7NAVHU423WOTE",
"amount": "688.4065454"
}

Advantages of this approach:

  • Scalable & Robust. It does not require additional resources if / when your transaction activity grows over time.
  • Get status of payments as they happen in real-time using the memo supplied in conjuction with the business process implemented.

Additional resources

Stellar Documentation

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store