Skip to main content

Signals from Following

Query signals (deposits and redemptions) from accounts that a specific user follows. This enables building personalized social activity feeds.

Query Structure​

query GetSignalsFromFollowing(
$account_id: String!
$limit: Int
$offset: Int
$where: signals_from_following_bool_exp
) {
signals_from_following(
args: { account_id: $account_id }
where: $where
limit: $limit
offset: $offset
order_by: { created_at: desc }
) {
id
delta
account {
id
label
image
}
term {
atom {
term_id
label
image
}
}
triple_id
created_at
}
}

Variables​

VariableTypeRequiredDescription
account_idStringYesThe account whose following list to use
limitIntNoMaximum results (default: 20)
offsetIntNoPagination offset
wheresignals_from_following_bool_expNoAdditional filters
{
"account_id": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
"limit": 20,
"offset": 0
}

Response Fields​

FieldTypeDescription
idStringSignal identifier
deltaStringAmount in wei
accountAccountAccount that made the signal
termTermRelated term (contains nested atom with label/image)
triple_idStringRelated triple ID (if triple signal)
created_atDateTimeEvent timestamp

Expected Response​

{
"data": {
"signals_from_following": [
{
"id": "0x123...-1",
"delta": "1000000000000000000",
"account": {
"id": "0xabc...",
"label": "alice.eth",
"image": "ipfs://Qm..."
},
"term": {
"atom": {
"id": "0x57d94c...",
"label": "Ethereum",
"image": "ipfs://Qm..."
}
},
"triple_id": null,
"created_at": "2024-01-15T10:30:00Z"
}
]
}
}

Interactive Example​

Query

query GetSignalsFromFollowing($account_id: String!, $limit: Int!) {
  signals_from_following(
    args: { account_id: $account_id }
    limit: $limit
    order_by: { created_at: desc }
  ) {
    id
    delta
    account {
      label
      image
    }
    term {
      atom {
        label
      }
    }
    created_at
  }
}

Variables

Click "Run Query" to execute the GraphQL query and see results

Use Cases​

Social Activity Feed​

Build a personalized feed showing activity from followed accounts:

async function getSocialFeed(
accountId: string,
options: { limit?: number; offset?: number } = {}
) {
const query = `
query GetSocialFeed(
$account_id: String!
$limit: Int!
$offset: Int!
) {
signals_from_following(
args: { account_id: $account_id }
limit: $limit
offset: $offset
order_by: { created_at: desc }
) {
id
delta
account {
id
label
image
}
term {
atom {
label
image
}
}
triple_id
created_at
}
}
`

const data = await client.request(query, {
account_id: accountId,
limit: options.limit || 20,
offset: options.offset || 0
})

return data.signals_from_following.map(signal => ({
...signal,
formattedMessage: formatActivityMessage(signal)
}))
}

function formatActivityMessage(signal: Signal): string {
const target = signal.term?.atom?.label ?? `Triple ${signal.triple_id}`

const amount = formatEther(signal.delta)

return `${signal.account.label} signaled on ${target} (${amount} ETH)`
}

React Social Feed Component​

function SocialFeed({ accountId }: { accountId: string }) {
const [offset, setOffset] = useState(0)
const LIMIT = 20

const { data, loading, fetchMore } = useQuery(GET_SIGNALS_FROM_FOLLOWING, {
variables: {
account_id: accountId,
limit: LIMIT,
offset: 0
}
})

if (loading && !data) return <Spinner />

const signals = data?.signals_from_following || []

const loadMore = () => {
fetchMore({
variables: { offset: signals.length }
})
}

return (
<div className="social-feed">
<h2>Activity from People You Follow</h2>
{signals.length === 0 ? (
<p>No recent activity from people you follow</p>
) : (
<>
{signals.map(signal => (
<SignalCard key={signal.id} signal={signal} />
))}
<button onClick={loadMore}>Load More</button>
</>
)}
</div>
)
}

function SignalCard({ signal }: { signal: Signal }) {
return (
<div className="signal-card">
<img src={signal.account.image} alt={signal.account.label} />
<div className="content">
<strong>{signal.account.label}</strong>
<span>signaled on</span>
<span className="target">
{signal.term?.atom?.label ?? `Triple ${signal.triple_id}`}
</span>
</div>
<div className="amount">
{formatEther(signal.delta)} ETH
</div>
<time>{formatRelativeTime(signal.created_at)}</time>
</div>
)
}

Filter by Deposits​

Show only deposit signals from followed accounts:

async function getDepositsFromFollowing(accountId: string) {
const query = `
query GetDepositsFromFollowing($account_id: String!) {
signals_from_following(
args: { account_id: $account_id }
where: { deposit_id: { _is_null: false } }
order_by: { delta: desc }
limit: 50
) {
id
delta
account { label }
term {
atom { label }
}
created_at
}
}
`

return client.request(query, { account_id: accountId })
}

How Following Works​

The signals_from_following query uses the social graph built from:

  • "Follow" triples where the account is the subject
  • Positions on "Follow" atoms involving the account

To see who an account follows, use the Following Query.

Best Practices​

  1. Implement pagination - Social feeds can grow large
  2. Show relative timestamps - "2 hours ago" is more readable
  3. Group by time - Consider grouping signals by day
  4. Cache appropriately - Feed data changes frequently