Skip to main content

Solana Transaction Signers API

A Solana transaction can be signed by more than one account. Transaction.Signer returns only the first one, the fee payer. Transaction.Signers returns the full list, in the order they appear in the transaction.

The first element of Signers is always equal to Signer, so existing queries keep working. Every query below was run against the live API on 2026-10-21; the IDE link opens it ready to run.

Why the full list matters​

Aggregators and wallet relayers often pay the fee for the user. Take this Jupiter swap:

  • Signer (fee payer): FHpcNSe6tb2n15bAdq4BkeYWGyZKFD7yLYrH92ng7wCT
  • The trader who signed the swap: Be24Gbf5KisDk1LcWWZsBn8dvB816By7YzYF5zWZnRR6

Filtering on Signer alone misses this trade. Filtering on Signers with includes catches it in any position.

Where it is available​

Transaction.Signers is exposed on the Solana cubes that carry a Transaction block, including Transactions and DEXTrades, in queries and subscriptions. It is also in the Kafka protobuf streams.

Filters and functions for the list​

NeedSyntax
Transaction signed by an address, any positionwhere: {Transaction: {Signers: {includes: {is: "ADDRESS"}}}}
Address signed but is not the fee payeradd notStartsWith: {is: "ADDRESS"} to the same filter
More than one signerwhere: {Transaction: {Signers: {length: {gt: 1}}}}
Number of signers as a fieldSignersCount: array_length(of: Transaction_Signers)
Number of signers in arithmeticcalculate(expression: "length($Transaction_Signers)")
Sort by signer countorderBy: {descendingByField: "SignersCount"}

Signers of recent transactions​

Signer and Signers side by side. On single-signer transactions the list has one element, equal to Signer.

Run in IDE

query SolanaTransactionSignersLatest {
Solana(dataset: realtime) {
Transactions(limit: {count: 10}, orderBy: {descending: Block_Time}) {
Block { Time }
Transaction { Signature Signer Signers }
}
}
}

Signers with their count​

array_length returns the number of signers as a field you can alias.

Run in IDE

query SolanaTransactionSignersCount {
Solana(dataset: realtime) {
Transactions(limit: {count: 10}, orderBy: {descending: Block_Time}) {
Transaction { Signature Signers }
SignersCount: array_length(of: Transaction_Signers)
}
}
}

Multi-signer transactions only​

The length filter on the list keeps only transactions with more than one signer.

Run in IDE

query SolanaMultiSignerTransactions {
Solana(dataset: realtime) {
Transactions(
limit: {count: 10}
orderBy: {descending: Block_Time}
where: {Transaction: {Signers: {length: {gt: 1}}}}
) {
Transaction { Signature Signers }
SignersCount: array_length(of: Transaction_Signers)
}
}
}

Transactions with the most signers​

Order by the aliased count with descendingByField.

Run in IDE

query SolanaTransactionsMostSigners {
Solana(dataset: realtime) {
Transactions(limit: {count: 10}, orderBy: {descendingByField: "SignersCount"}) {
Transaction { Signature Signers }
SignersCount: array_length(of: Transaction_Signers)
}
}
}

Transactions signed by one address, in any position​

includes matches the address wherever it sits in the list, fee payer or not.

Run in IDE

query SolanaTransactionsByAnySigner {
Solana(dataset: realtime) {
Transactions(
limit: {count: 10}
orderBy: {descending: Block_Time}
where: {Transaction: {Signers: {includes: {is: "Be24Gbf5KisDk1LcWWZsBn8dvB816By7YzYF5zWZnRR6"}}}}
) {
Transaction { Signature Signer Signers }
}
}
}

DEX trades signed by one address​

The same filter on DEXTrades returns the swaps a wallet signed, including swaps where an aggregator or relayer paid the fee.

Run in IDE

query SolanaDexTradesByAnySigner {
Solana(dataset: realtime) {
DEXTrades(
limit: {count: 10}
orderBy: {descending: Block_Time}
where: {Transaction: {Signers: {includes: {is: "Be24Gbf5KisDk1LcWWZsBn8dvB816By7YzYF5zWZnRR6"}}}}
) {
Block { Time }
Transaction { Signature Signers }
Trade {
Buy { Amount Currency { Symbol } }
Sell { Amount Currency { Symbol } }
}
}
}
}

Address signed but is not the fee payer​

Combine includes with notStartsWith. The address is in the list, but it is not the first element, so someone else paid the fee.

Run in IDE

query SolanaTransactionsSignerNotFeePayer {
Solana(dataset: realtime) {
Transactions(
limit: {count: 10}
orderBy: {descending: Block_Time}
where: {Transaction: {Signers: {
includes: {is: "Be24Gbf5KisDk1LcWWZsBn8dvB816By7YzYF5zWZnRR6"}
notStartsWith: {is: "Be24Gbf5KisDk1LcWWZsBn8dvB816By7YzYF5zWZnRR6"}
}}}
) {
Transaction { Signature Signer Signers }
}
}
}

Signer count through calculate​

length() inside calculate gives the same count and can be used in arithmetic.

Run in IDE

query SolanaSignersCountCalculate {
Solana(dataset: realtime) {
Transactions(limit: {count: 5}, orderBy: {descending: Block_Time}) {
Transaction { Signature Signers }
SignersCount: calculate(expression: "length($Transaction_Signers)")
Doubled: calculate(expression: "length($Transaction_Signers) * 2")
}
}
}

Subscriptions​

Live DEX trades with all signers​

Run in IDE

subscription SolanaDexTradesStreamAllSigners {
Solana {
DEXTrades {
Block { Time }
Transaction { Signature Signer Signers }
}
}
}

Live DEX trades signed by one address​

Run in IDE

subscription SolanaDexTradesStreamOneSigner {
Solana {
DEXTrades(where: {Transaction: {Signers: {includes: {is: "Be24Gbf5KisDk1LcWWZsBn8dvB816By7YzYF5zWZnRR6"}}}}) {
Transaction { Signature Signers }
}
}
}

Live multi-signer transactions with count​

Run in IDE

subscription SolanaMultiSignerTransactionsStream {
Solana {
Transactions(where: {Transaction: {Signers: {length: {gt: 1}}}}) {
Transaction { Signature Signers }
SignersCount: array_length(of: Transaction_Signers)
}
}
}

Frequently Asked Questions

What is the difference between Signer and Signers?

Signer is the first signer of the transaction, the fee payer. Signers is the full ordered list of signing accounts; its first element equals Signer.

How do I find trades by the real trader when an aggregator pays the fee?

Filter DEXTrades with Transaction: {Signers: {includes: {is: ADDRESS}}}. It matches the address in any position of the list, not only the fee payer.

Does adding Signers change existing queries?

No. Signer keeps returning the fee payer. Signers is an additional field.

Build with Bitquery

Ready to run this in production?

Get an API key and run these queries in minutes, or talk to us about plans and enterprise delivery.