Overview
In both methods, the sequence number is βspentβ by the transaction source account.
Method 1: Transaction signing
Full transaction signing is the simpler approach where the same account acts as both the transaction source (paying fees and consuming sequence) and the authorizer of the contract invocation. This method works only with G-accounts (Stellar accounts starting withG).
When to use
- The calling account owns the keys and can sign the full transaction
- The caller is willing to pay transaction fees, which can only be paid in XLM and by a G-account
- You want the simplest integration path
- Single-party authorization is sufficient
How it works
- Client builds a transaction with an
invokeHostFunctionoperation - Client simulates the transaction to get resource requirements and footprint
- Client signs the entire transaction envelope with the source accountβs keypair
- Client submits the signed transaction to the network
sorobanCredentialsSourceAccount credential type.
Code example
Source account authorizationFor transaction signing,
prepareTransaction handles simulation internally. Since the source accountβs signature on the transaction envelope implicitly authorizes the invocation, no separate auth entry signing is neededβand therefore no second simulation is required.Key characteristics
- Sequence number: Consumed from the source account
- Fees: Paid by the source account
- Authorization: Implicit via transaction signature (for source account credentials)
- Limitation: Cannot be used with C-accounts (contract accounts)
Method 2: Auth-entry signing
Auth-entry signing decouples authorization from transaction submission. The authorizer signs only the specific contract invocation (an βauth entryβ), while a separate account acts as the transaction source, paying fees and consuming its own sequence number. This method works for either G-account or C-account clients.When to use
- The end-user has a C-account (commonly a smart wallet) β Method 2 is the only option for C-accounts, as they cannot sign transaction envelopes. G-accounts can also use this method.
- The end-user doesnβt (need to) have XLM to pay for fees
- Applications want a fine-grained control over which parts of the contract invocation (and subinvocations) are authorized by each account.
- Building smart contract protocols where the end-user doesnβt submit the transaction
- Building payment protocols where the transaction source account will be defined at a later point in time
How it works
- Client builds the transaction using
AssembledTransaction - Client simulates (Recording Mode) to get the authorization tree
- Client signs the auth entries using
signAuthEntries - Client optionally re-simulates (Enforcing Mode) to validate their signatures
- Client sends the transaction XDR to the fee-payer
- Fee-payer parses the XDR and rebuilds with its own G-account as source
- Fee-payer performs security verifications π¨ to ensure the incoming transaction does not contain any malicious code.
- Fee-payer simulates (Enforcing Mode) to catch errors before paying fees
- Fee-payer signs the transaction envelope and submits
Simulation modes: Recording vs Enforcing
Transaction simulation has two modes that are critical to understand:Auth entry structure
An auth entry signature authorizes a specific invocation tree and includes:- Address: The account authorizing the invocation
- Signature expiration ledger: When the signature becomes invalid (ledger-based, not timestamp)
- Nonce: A unique value for replay protection
- Signature: Signs the SHA-256 hash of the
ENVELOPE_TYPE_SOROBAN_AUTHORIZATIONpreimage
Signature expirationAuth entry signatures expire based on ledger numbers, not timestamps. A typical offset is between 12 and 60 ledgers (approximately 1-5 minutes). The signature is valid until and including the
signatureExpirationLedger, but invalid at signatureExpirationLedger + 1.Keep expiration windows as small as viable β shorter windows are safer and result in lower transaction costs.Code example: Using AssembledTransaction
This example shows a token transfer where the sender (client) uses AssembledTransaction to build and sign auth entries, then sends the transaction XDR to a fee-payer for submission.
Step 1: Client builds and signs auth entries
Step 2: Fee-payer rebuilds and submits
Key characteristics
- Sequence number: Consumed from the fee-payer account
- Fees: Paid by the fee-payer account (in XLM)
- Client authorization: Explicit via signed auth entries (separate from transaction signature)
- Flexibility: Works with both G-accounts and C-accounts (contract accounts)
- Use case: Sponsored transactions, relayed transactions, smart wallets, multi-party authorization, fine-grained authorization control
C-account (smart wallet) authorization
C-accounts (contract accounts starting withC) cannot sign transaction envelopesβthey can only authorize via auth entries. This is because C-accounts donβt have traditional keypairs; their authorization logic is defined by the contract code itself (e.g., a smart wallet contract that verifies passkey signatures).
For C-accounts:
- The auth entry signature is produced by the contractβs authentication mechanism (e.g., passkeys, multisig logic)
- A separate G-account must always act as the transaction source to pay fees
- Wallet interfaces and signing utilities provide
signAuthEntryAPIs for this purpose
Signing auth entries with different methods
UsingbasicNodeSigner for G-accounts (Node.js/backend)
The basicNodeSigner utility creates signing functions from a keypair, providing both signAuthEntry and signTransaction methods. This is useful for backend services or testing.
signAuthEntry for C-accounts (smart wallets) where the signing logic is defined by the contract.
Comparison summary
Visual: Transaction signing
Visual: Auth-entry signing
Real-world use case: Sponsored transactions
A common pattern in payment protocols is for a fee-payer to submit transactions on behalf of users:- Client builds a transaction and simulates it (Recording Mode)
- Client signs the auth entries (authorizing the payment)
- Client optionally re-simulates (Enforcing Mode) to validate signatures
- Client sends the signed auth entries to the fee-payer service
- Fee-payer rebuilds the transaction with its own G-account as source
- Fee-payer re-simulates (Enforcing Mode) to get accurate resource estimates and validate signatures
- Fee-payer signs the transaction envelope and submits
Note on Fee-bump transactions
Regardless of the method, the user can still use fee bump transactions as an additional layer in order to separate the account spending their sequence number from the account paying the fees. More info on fee bump transactions can be found in the Fee-bump transactions guide.Common pitfalls and gotchas
- Using Horizon URLs: Soroban signing requires Soroban RPC, not Horizon. Refer to Soroban RPC Providers for the correct URL to use.
- Forgetting to assemble: Fee-payer flows must
assembleTransactionafter simulation to apply footprint + resource fees. - Missing auth on rebuilt ops: When rebuilding, include
sorobanDatain theinvokeHostFunctionoperation. - Wrong signer: C-accounts cannot sign envelopes, only auth entries.
- Stale auth expiration: Keep
signatureExpirationLedgershort and aligned with expected submission time.
Further reading
- Transaction simulation β Details on simulation and authorization modes
- Multi-party auth example β Walkthrough of multi-party signing in simulation using full transaction signing
- Contract authorization β How
require_authworks in contracts - Sign authorization entries with Varial β Wallet integration for auth entry signing
- Send to and receive from C-accounts β Working with contract accounts
- Fee-bump transactions β Using fee bump transactions to pay for transaction fees on behalf of another account without re-signing the transaction
- Stellar auth example (community) β End-to-end auth-entry signing walkthrough
- Stellar Asset Contract (SAC) β Background on the SAC
transfer, used in the code examples above