description | layout | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Learn how to recommend users based on token transfers |
|
Token transfers between two parties are a good indication that the parties involved know each other. Therefore, you can also use token transfers to build your recommendation engine.
To build such a recommendation engine, Airstack provides a TokenTransfers
API for you to fetch the users involved in a given user's all ERC20/721/1155 token transfers across Ethereum, Base, Degen Chain, and other Airstack-supported chains.
The list of users, then can be compiled and returned to your application as recommendations.
In this guide you will learn how to use Airstack to:
- Get Token Transfers Sent From A User on Ethereum
- Get Token Transfers Received By A User on Ethereum
- Get Token Transfers Sent From A User on Base
- Get Token Transfers Received By A User on Base
- Get Token Transfers Sent From A User on Multiple Chains
- Get Token Transfers Received By A User on Multiple Chains
- Get The Most Recent Token Transfers Sent From A User
- Get The Most Recent Token Transfers Received By A User
- An Airstack account
- Basic knowledge of GraphQL
If you are using JavaScript/TypeScript or Python, Install the Airstack SDK:
{% tabs %} {% tab title="npm" %} React
npm install @airstack/airstack-react
Node
npm install @airstack/node
{% endtab %}
{% tab title="yarn" %} React
yarn add @airstack/airstack-react
Node
yarn add @airstack/node
{% endtab %}
{% tab title="pnpm" %} React
pnpm install @airstack/airstack-react
Node
pnpm install @airstack/node
{% endtab %}
{% tab title="pip" %}
pip install airstack
{% endtab %} {% endtabs %}
Then, add the following snippets to your code:
{% tabs %} {% tab title="React" %}
import { init, useQuery } from "@airstack/airstack-react";
init("YOUR_AIRSTACK_API_KEY");
const query = `YOUR_QUERY`; // Replace with GraphQL Query
const Component = () => {
const { data, loading, error } = useQuery(query);
if (data) {
return <p>Data: {JSON.stringify(data)}</p>;
}
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
};
{% endtab %}
{% tab title="Node" %}
import { init, fetchQuery } from "@airstack/node";
init("YOUR_AIRSTACK_API_KEY");
const query = `YOUR_QUERY`; // Replace with GraphQL Query
const { data, error } = await fetchQuery(query);
console.log("data:", data);
console.log("error:", error);
{% endtab %}
{% tab title="Python" %}
import asyncio
from airstack.execute_query import AirstackClient
api_client = AirstackClient(api_key="YOUR_AIRSTACK_API_KEY")
query = """YOUR_QUERY""" # Replace with GraphQL Query
async def main():
execute_query_client = api_client.create_execute_query_object(
query=query)
query_response = await execute_query_client.execute_query()
print(query_response.data)
asyncio.run(main())
{% endtab %} {% endtabs %}
To access the Airstack APIs in other languages, you can use https://api.airstack.xyz/gql as your GraphQL endpoint.
🤖 AI Natural Language
Airstack provides an AI solution for you to build GraphQL queries to fulfill your use case easily. You can find the AI prompt of each query in the demo's caption or title for yourself to try.
Airstack AI (Demo)
You can fetch all token transfers sent from a given user, e.g. betashop.eth
, on Ethereum by using the TokenTransfers
API:
{% embed url="https://app.airstack.xyz/query/ZGtUdm88Lv" %} Show me token transfers sent from betashop.eth on Ethereum {% endembed %}
{% tabs %} {% tab title="Query" %}
query GetTokenTransfers {
TokenTransfers(
input: {
filter: {
# Only get token transfers from betashop.eth
from: {_eq: "betashop.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "betashop.eth"]}
}
},
blockchain: ethereum,
limit: 50
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
to {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
}
{% endtab %}
{% tab title="Response" %}
{
"data": {
"TokenTransfers": {
"TokenTransfer": [
{
"formattedAmount": 25,
"tokenType": "ERC20",
"token": {
"name": "USD Coin"
},
"to": {
"addresses": [
// this user received 25 USDC from betashop.eth
"0x427a1c6dcaad92f886020a61e0b85be8e1c5ead5"
],
"domains": [
{
"name": "mrwildenfree.eth"
}
],
"socials": [
{
"dappName": "lens",
"profileName": "lens/@mrwildenfree"
},
{
"dappName": "farcaster",
"profileName": "mrwildenfree"
}
],
"xmtp": [
{
"isXMTPEnabled": true
}
]
}
},
{
"formattedAmount": 25,
"tokenType": "ERC20",
"token": {
"name": "USD Coin"
},
"to": {
"addresses": [
// This user received 25 USDC from betashop.eth
"0x7ce0448b0fafab6cace981fffa967cf380a2cc33"
],
"domains": [
{
"name": "jameshih.eth"
}
],
"socials": [
{
"dappName": "farcaster",
"profileName": "jameshih.eth"
}
],
"xmtp": null
}
},
// Other token transfers from betashop.eth on Ethereum
]
}
}
}
{% endtab %} {% endtabs %}
All the users returned from the to
response field can be compiled and returned as a recommendation in your application.
You can fetch all token transfers received by a given user, e.g. betashop.eth
, on Ethereum by using the TokenTransfers
API:
{% embed url="https://app.airstack.xyz/query/d0vekk7Ako" %} Show me token transfers received by betashop.eth on Ethereum {% endembed %}
{% tabs %} {% tab title="Query" %}
query GetTokenTransfers {
TokenTransfers(
input: {
filter: {
# Only get token transfers to betashop.eth
to: {_eq: "betashop.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "betashop.eth"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]}
}
},
blockchain: ethereum,
limit: 50
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
from {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
}
{% endtab %}
{% tab title="Response" %}
{
"data": {
"TokenTransfers": {
"TokenTransfer": [
{
"formattedAmount": 1,
"tokenType": "ERC721",
"token": {
"name": "ETHGlobal Pragma Lisbon"
},
"from": {
"addresses": [
// This user sent 1 ETHGlobal Pragma Lisbon NFT to betshop.eth
"0x8f07bc36ff569312fdc41f3867d80bbd2fe94b76"
],
"domains": [
{
"name": "jacob.willemsma.eth"
},
// Other ENS domains
],
"socials": [
{
"dappName": "lens",
"profileName": "lens/@jacobwillemsma"
},
{
"dappName": "farcaster",
"profileName": "wj"
}
],
"xmtp": null
}
},
{
"formattedAmount": 0.00005,
"tokenType": "ERC20",
"token": {
"name": "Wrapped Ether"
},
"from": {
"addresses": [
// This user sent 0.00005 WETH to betashop.eth
"0xe5bfab544eca83849c53464f85b7164375bdaac1"
],
"domains": null,
"socials": null,
"xmtp": null
}
},
// Other Token Transfers received by betashop.eth on Ethereum
]
}
}
}
{% endtab %} {% endtabs %}
All the users returned from the from
response field can be compiled and returned as a recommendation in your application.
You can fetch all token transfers sent from a given user, e.g. jessepollak.eth
, on Base by using the TokenTransfers
API:
{% embed url="https://app.airstack.xyz/query/ubt2YJHZHj" %} Show me token transfers sent from jessepollak.eth on Base {% endembed %}
{% tabs %} {% tab title="Query" %}
query GetTokenTransfers {
TokenTransfers(
input: {
filter: {
# Only get token transfers from jessepollak.eth
from: {_eq: "jessepollak.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "jessepollak.eth"]}
}
},
blockchain: base,
limit: 50
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
to {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
}
{% endtab %}
{% tab title="Response" %}
{
"data": {
"TokenTransfers": {
"TokenTransfer": [
{
"formattedAmount": 100,
"tokenType": "ERC20",
"token": {
"name": "USD Coin"
},
"to": {
"addresses": [
// jessepollak.eth sent 100 USDC to this user
"0xdb6f1920a889355780af7570773609bd8cb1f498"
],
"domains": null,
"socials": null,
"xmtp": null
}
},
{
"formattedAmount": 99,
"tokenType": "ERC20",
"token": {
"name": "USD Base Coin"
},
"to": {
"addresses": [
// jessepollak.eth sent 99 USD Base Coin to this user
"0x6cfc03917344d9403f77bbc8a62bf138da124715"
],
"domains": null,
"socials": null,
"xmtp": null
}
},
// Other Base token transfers sent by jessepollak.eth
]
}
}
}
{% endtab %} {% endtabs %}
All the users returned from the to
response field can be compiled and returned as a recommendation in your application.
You can fetch all token transfers received by a given user, e.g. barmstrong.eth
, on Base by using the TokenTransfers
API:
{% embed url="https://app.airstack.xyz/query/RIffwTnhus" %} Show me token transfers received by barmstrong.eth on Base {% endembed %}
{% tabs %} {% tab title="Query" %}
query GetTokenTransfers {
TokenTransfers(
input: {
filter: {
# Only get token transfers to barmstrong.eth
to: {_eq: "barmstrong.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "barmstrong.eth"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]}
}
},
blockchain: base,
limit: 50
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
from {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
}
{% endtab %}
{% tab title="Response" %}
{
"data": {
"TokenTransfers": {
"TokenTransfer": [
{
"formattedAmount": 1,
"tokenType": "ERC721",
"token": {
"name": "BasePunks"
},
"from": {
"addresses": [
// This user sent 1 BasePunks NFT to barmstrong.eth
"0xb3ce96c9b78e1f18ba250f909825cdfb50e9cafc"
],
"domains": null,
"socials": null,
"xmtp": null
}
},
{
"formattedAmount": 1,
"tokenType": "ERC721",
"token": {
"name": "Bullcasso"
},
"from": {
"addresses": [
// This user sent 1 Bullcasso NFT to barmstrong.eth
"0x3dc9c871672c3cccae681cc78df40394c49ebc09"
],
"domains": null,
"socials": null,
"xmtp": [
{
"isXMTPEnabled": true
}
]
}
},
// Other Token Transfers received by barmstrong.eth on Base
]
}
}
}
{% endtab %} {% endtabs %}
All the users returned from the from
response field can be compiled and returned as a recommendation in your application.
You can fetch all token transfers sent from a given user, e.g. betashop.eth
, across multiple chains, such as Ethereum, Base, Degen Chain, and other Airstack-supported chains, by using the TokenTransfers
API:
{% embed url="https://app.airstack.xyz/query/yXNz4iBC7o" %} Show me all token transfers sent from betashop.eth on Ethereum and Base {% endembed %}
{% tabs %} {% tab title="Query" %}
query GetTokenTransfers {
# first query on Ethereum
Ethereum: TokenTransfers(
input: {
filter: {
# Only get token transfers from betashop.eth
from: {_eq: "betashop.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "betashop.eth"]}
}
},
blockchain: ethereum,
limit: 50
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
to {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
# second query on Base
Base: TokenTransfers(
input: {
filter: {
# Only get token transfers from betashop.eth
from: {_eq: "betashop.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "betashop.eth"]}
}
},
blockchain: base,
limit: 50
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
to {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
}
{% endtab %}
{% tab title="Response" %}
{
"data": {
"Ethereum": {
"TokenTransfer": [
{
"formattedAmount": 25,
"tokenType": "ERC20",
"token": {
"name": "USD Coin"
},
"to": {
"addresses": [
// betashop.eth sent 25 USDC to this user
"0x427a1c6dcaad92f886020a61e0b85be8e1c5ead5"
],
"domains": [
{
"name": "mrwildenfree.eth"
}
],
"socials": [
{
"dappName": "lens",
"profileName": "lens/@mrwildenfree"
},
{
"dappName": "farcaster",
"profileName": "mrwildenfree"
}
],
"xmtp": [
{
"isXMTPEnabled": true
}
]
}
},
// Other token transfers sent by betashop.eth on Ethereum
]
},
"Base": {
"TokenTransfer": [
{
"formattedAmount": 100,
"tokenType": "ERC20",
"token": {
"name": "USD Coin"
},
"to": {
"addresses": [
"0x9bb4d44e6963260a1850926e8f6beb8d5803836f"
],
"domains": null,
"socials": null,
"xmtp": null
}
}
]
}
}
}
{% endtab %} {% endtabs %}
All the users returned from the to
response field can be compiled and returned as a recommendation in your application.
You can fetch all token transfers received by a given user, e.g. betashop.eth
, across multiple chains, such as Ethereum, Gold, Zora, and Base, by using the TokenTransfers
API:
{% embed url="https://app.airstack.xyz/query/nvSWeogcbI" %} Show me token transfers received by betashop.eth on Ethereum and Base {% endembed %}
{% tabs %} {% tab title="Query" %}
query GetTokenTransfers {
# first query on Ethereum
Ethereum: TokenTransfers(
input: {
filter: {
# Only get token transfers to betashop.eth
to: {_eq: "betashop.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "betashop.eth"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]}
}
},
blockchain: ethereum,
limit: 50
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
from {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
# second query on Base
Base: TokenTransfers(
input: {
filter: {
# Only get token transfers to betashop.eth
to: {_eq: "betashop.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "betashop.eth"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]}
}
},
blockchain: base,
limit: 50
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
from {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
}
{% endtab %}
{% tab title="Response" %}
{
"data": {
"Ethereum": {
"TokenTransfer": [
{
"formattedAmount": 1,
"tokenType": "ERC721",
"token": {
"name": "ETHGlobal Pragma Lisbon"
},
"from": {
"addresses": [
// This user sent 1 ETHGlobal Pragma Lisbon NFT to betshop.eth
"0x8f07bc36ff569312fdc41f3867d80bbd2fe94b76"
],
"domains": [
{
"name": "jacob.willemsma.eth"
},
// Other ENS domains
],
"socials": [
{
"dappName": "lens",
"profileName": "lens/@jacobwillemsma"
},
{
"dappName": "farcaster",
"profileName": "wj"
}
],
"xmtp": null
}
},
// Other Token Transfers received by betashop.eth on Ethereum
]
},
"Base": {
"TokenTransfer": null // No Tokens received by betashop.eth on Base
}
}
}
{% endtab %} {% endtabs %}
All the users returned from the from
response field can be compiled and returned as a recommendation in your application.
You can fetch all most recent token transfers sent from a given user, e.g. betashop.eth
, across multiple chains, such as Ethereum, Gold, Zora, and Base, by using the TokenTransfers
API:
{% embed url="https://app.airstack.xyz/query/eVeZFo9rNH" %} Show me the most recent token transfers sent from betashop.eth on Ethereum and Base {% endembed %}
{% tabs %} {% tab title="Query" %}
query GetTokenTransfers {
# first query on Ethereum
Ethereum: TokenTransfers(
input: {
filter: {
# Only get token transfers from betashop.eth
from: { _eq: "betashop.eth" }
# Only get token transfers with non-zero amount
formattedAmount: { _gt: 0 }
# Remove all minting/burning + self-transfer
_nor: {
from: {
_in: [
"0x0000000000000000000000000000000000000000"
"0x000000000000000000000000000000000000dEaD"
]
}
to: {
_in: [
"0x0000000000000000000000000000000000000000"
"0x000000000000000000000000000000000000dEaD"
"betashop.eth"
]
}
}
}
blockchain: ethereum
limit: 50
order: { blockTimestamp: DESC } # Order transfers by blocktimestamp in descending order
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
to {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
# second query on Base
Base: TokenTransfers(
input: {
filter: {
# Only get token transfers from betashop.eth
from: { _eq: "betashop.eth" }
# Only get token transfers with non-zero amount
formattedAmount: { _gt: 0 }
# Remove all minting/burning + self-transfer
_nor: {
from: {
_in: [
"0x0000000000000000000000000000000000000000"
"0x000000000000000000000000000000000000dEaD"
]
}
to: {
_in: [
"0x0000000000000000000000000000000000000000"
"0x000000000000000000000000000000000000dEaD"
"betashop.eth"
]
}
}
}
blockchain: base
limit: 50
order: { blockTimestamp: DESC } # Order transfers by blocktimestamp in descending order
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
to {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
}
{% endtab %}
{% tab title="Response" %}
{
"data": {
"Ethereum": {
"TokenTransfer": [
{
"formattedAmount": 125,
"tokenType": "ERC20",
"token": {
"name": "USD Coin"
},
"to": {
"addresses": [
// betashop.eth sent 125 USDC to this user
"0x3a23f943181408eac424116af7b7790c94cb97a5"
],
"domains": null,
"socials": null,
"xmtp": null
}
},
// Other most recent token transfers sent by betashop.eth on Ethereum
]
},
"Base": {
"TokenTransfer": [
{
"formattedAmount": 100,
"tokenType": "ERC20",
"token": {
"name": "USD Coin"
},
"to": {
"addresses": [
// betashop.eth sent 100 USDC to this user
"0x9bb4d44e6963260a1850926e8f6beb8d5803836f"
],
"domains": null,
"socials": null,
"xmtp": null
}
}
]
}
}
}
{% endtab %} {% endtabs %}
All the users returned from the to
response field can be compiled and returned as a recommendation in your application.
You can fetch most recent token transfers received by a given user, e.g. betashop.eth
, across multiple chains, such as Ethereum, Gold, Zora, and Base, by using the TokenTransfers
API:
{% embed url="https://app.airstack.xyz/query/eVeZFo9rNH" %} Show me the most recent token transfers received by betashop.eth on Ethereum and Base {% endembed %}
{% tabs %} {% tab title="Query" %}
query GetTokenTransfers {
Ethereum: TokenTransfers(
input: {
filter: {
# Only get token transfers to betashop.eth
to: {_eq: "betashop.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "betashop.eth"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]}
}
},
blockchain: ethereum,
limit: 50,
order: { blockTimestamp: DESC } # Order transfers by blocktimestamp in descending order
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
from {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
Base: TokenTransfers(
input: {
filter: {
# Only get token transfers to betashop.eth
to: {_eq: "betashop.eth"},
# Only get token transfers with non-zero amount
formattedAmount: {_gt: 0},
# Remove all minting/burning + self-transfer
_nor: {
from: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD", "betashop.eth"]},
to: {_in: ["0x0000000000000000000000000000000000000000", "0x000000000000000000000000000000000000dEaD"]}
}
},
blockchain: base,
limit: 50,
order: { blockTimestamp: DESC } # Order transfers by blocktimestamp in descending order
}
) {
TokenTransfer {
formattedAmount
tokenType
token {
name
}
from {
addresses
domains {
name
}
socials {
dappName
profileName
}
xmtp {
isXMTPEnabled
}
}
}
}
}
{% endtab %}
{% tab title="Response" %}
{
"data": {
"Ethereum": {
"TokenTransfer": [
{
"formattedAmount": 1250,
"tokenType": "ERC20",
"token": {
"name": "USD Coin"
},
"from": {
"addresses": [
// This user sent 1250 USDC to betashop.eth
"0xe2b9be8c62dd8f3d416fc6ba766a17de7f81d0e9"
],
"domains": [
{
"name": "airstack.eth"
}
],
"socials": null,
"xmtp": null
}
},
// Other most recent token transfers received by betashop.eth on Ethereum
]
},
"Base": {
"TokenTransfer": null // No tokens received by betashop.eth on Base
}
}
}
{% endtab %} {% endtabs %}
All the users returned from the from
response field can be compiled and returned as a recommendation in your application.
If you have any questions or need help regarding integrating or building recommendation engine with token transfer data into your application, please join our Airstack's Telegram group.