{"meta":{"matchMode":"vector","matchModeLabel":"vector-similarity ranking — conceptually related, not literal keyword truth (verify before relying)","source":"https://stellarlight.xyz/api/research","generatedAt":"2026-09-24T19:16:43.959Z","query":"soroban authorization","mode":"vector","model":"voyage-3","filters":{"source":null,"auditor":null,"protocol":null,"severity":null,"limit":8},"counts":{"returned":8,"total":null,"totalBasis":"unbounded-similarity-ranking"},"scoreModel":{"version":"research-confidence-1","fields":["relevance","freshness","authority"],"note":"confidence.score = 0.65·relevance + 0.15·freshness + 0.20·authority (relevance-floored). Results are returned in confidence order, best chunk per document; a document the query names by canonical identifier (CAP-NNNN / SEP-NNNN, any variant form) ranks first with relevance floored at 0.9. Recency-intent queries (latest/newest/recent/current/this-year…) re-rank by publication-dated freshness blended with confidence — maintenance/lastmod dates don't count — and the pool is supplemented with the corpus's newest publication-dated docs sharing the query's topic terms, scored by their real embedding similarity. Curated vertical-anchor docs (e.g. the canonical cross-chain asset-transfer how-to for consumer bridge intent) carry relevance floored at 0.85. A chunk containing EVERY query token verbatim (brand/lookup queries, e.g. a partner product name) carries relevance floored at 0.8 and is fetched into the pool even when cosine retrieval missed it — applied only while coverage is discriminating (at most 5 chunks in the pool carry it; widely-covered tokens are generic vocabulary, not a lookup key)."}},"results":[{"id":"6a50094abf7cbd0d4298a6bb","source":"cap","title":"Memo Authorization for Soroban","section":"Preamble","url":"https://github.com/stellar/stellar-protocol/blob/master/core/cap-0064.md","content":"## Preamble\n\n```\nCAP: 0064\nTitle: Memo Authorization for Soroban\nWorking Group:\n    Owner: dmkozh@stellar.org\n    Authors: Dmytro Kozhevin <@dmkozh>\n    Consulted: Leigh McCulloch <@leighmcculloch>, Siddharth Suresh <@sisuresh>\nStatus: Rejected\nCreated: 2025-01-09\nDiscussion: https://github.com/stellar/stellar-protocol/discussions/1610\nProtocol version: TBD\n```","chunkIndex":0,"publishedAt":"2025-01-09T00:00:00.000Z","observedAt":null,"docKind":null,"docVersionStatus":null,"auditor":null,"protocol":null,"severity":null,"capStatus":"Rejected","capProtocolVersion":null,"score":0.7201731204986572,"confidence":{"score":0.82,"label":"high","relevance":0.72,"freshness":1,"authority":1,"ageDays":null}},{"id":"6a500b90ab3ef06c37b2ef67","source":"dev-docs","title":"Authorization","section":"Soroban Authorization Framework​","url":"https://developers.stellar.org/docs/learn/fundamentals/contract-development/authorization","content":"## Soroban Authorization Framework​\n\nIf any of the steps above fails, then the authorization is considered unsuccessful.\n\nNotice, that authentication happens just once per tree, as the whole tree needs to be signed.\n\nMatching Authorized Invocation Trees​\nIn order for authorizations to succeed, all the require_auth/require_auth_for_args calls have to be covered by the corresponding SorobanAuthorizedInvocation trees in a transaction (defined in transaction XDR).\n\nFormally, this correspondence is defined as follows.\n\nGiven a top-level contract invocation I we can build a &#x27;contract invocation tree&#x27; T by tracing all the sub-contract calls (a directed edge A->B in the tree means &#x27;contract function A calls contract function B). Note, that we only consider the functions that are implemented in different contracts, i.e. any function calls that don&#x27;t involve a contract invocation via host call are considered to belong to the same node.\n\nLet&#x27;s say authorization is required from addresses A_1..A_N. Then for every address A_i there are two kinds of nodes in the invocation tree T: R-nodes that had a require_auth call for A_i and N-nodes that didn&#x27;t have such call. Then we remove all the N-nodes and all the edges from T and add the directed edges connecting the remaining R-nodes such that the edge goes from R_j to R_k if there was a path between R_j and R_k in T that doesn&#x27;t contain any other R-nodes. As a result we get a forest of SorobanAuthorizedInvocation trees for A_i. Notice, that these trees don&#x27;t have to have their root be I node (i.e. the top-level contract call), so it&#x27;s possible to e.g. batch the authorized call together without requiring signing the batching function.\n\nIn simpler terms, SorobanAuthorizedInvocation trees for an Address are subsets of the full invocation tree that are &#x27;condensed&#x27; to only contain invocations that have require_auth call for that Address.\n\nDuring the matching process that happens for every require_auth host tries to match the current path in T to a SorobanAuthorizedInvocation tree for the corresponding Address. The path is considered to be matched only when there is a corresponding path of exhausted R nodes leading to the current call. This means that if the Address signs a sequence of calls A.foo->B.bar->C.baz, then its authorization check will fail in case if A.foo directly calls C.baz because C.baz strictly has to be called from B.bar.\n\nDuplicate Addresses​\nIn case if the same contract function calls require_auth for the same Address multiple times (e.g. when multiple operations from the same user are being batched), every require_auth call still has to have a corresponding node in the SorobanAuthorizedInvocation tree. Due to that, there might be multiple valid trees that make all the authorization checks pass. There is nothing wrong about that - the address still must have authorized all the invocations. The only requirement for such cases to be handled correctly is to ensure that the require_auth calls for an Address happen before the corresponding sub-contract calls.\n\nEdit this pageLast updated on Dec 11, 2025 by Philip LiuPreviousState ArchivalNextErrors and Debugging\n- Soroban Authorization Framework\n- Contract-Specific Authorization\n- Account Abstraction\n- Secp256r1, passkeys and contract accounts\n- Advanced Concepts","chunkIndex":3,"publishedAt":"2025-12-11T00:00:00.000Z","observedAt":"2026-09-24T11:02:01.940Z","docKind":null,"docVersionStatus":null,"auditor":null,"protocol":null,"severity":null,"capStatus":null,"capProtocolVersion":null,"score":0.7251926064491272,"confidence":{"score":0.77,"label":"high","relevance":0.66,"freshness":1,"authority":0.95,"ageDays":null}},{"id":"6a151660d5ac3338bbd50ddc","source":"dev-docs","title":"Implement authentication and authorization","section":"Further reading​","url":"https://developers.stellar.org/docs/build/smart-contracts/example-contracts/auth","content":"## Further reading​\n\nAuthorization documentation provides more details on how Soroban auth framework works.\n\nTimelock and Single Offer examples demonstrate authorizing token operations on behalf of the user, which can be extended to any nested contract invocations.\n\nAtomic Swap example demonstrates multi-party authorization where multiple users sign their parts of the contract invocation.\n\nSimple Account example demonstrates a minimal contract account implementation and how __check_auth works end-to-end.\n\nEdit this pageLast updated on Jun 17, 2026 by Elliot VorisPreviousLoggingNextCross Contract Calls\n- Run the Example\n- Code\n- How it Works\n- Address\n- require_auth\n- Tests\n\n- Build the Contract\n- Run the Contract\n- Deploy\n- Invoke\n\n- Further reading","chunkIndex":7,"publishedAt":"2026-06-17T00:00:00.000Z","observedAt":"2026-09-24T11:02:01.940Z","docKind":null,"docVersionStatus":null,"auditor":null,"protocol":null,"severity":null,"capStatus":null,"capProtocolVersion":null,"score":0.7196441888809204,"confidence":{"score":0.76,"label":"high","relevance":0.64,"freshness":1,"authority":0.95,"ageDays":null}},{"id":"6a1516c3975750ee958a3d04","source":"audit","title":"Stellar Soroban Core — Veridise (Auditing Report for Soroban Stellar Soroban Core V2)","section":"V-SOR-VUL-002:","url":"https://stellarsecurityportal.com/report/28","content":"## V-SOR-VUL-002:\n\n# DenialofService\n# During\n# Authorization\n\nSeverity Critical Commit 2674d86 \nType Denial of Service Status Investigated \nFile(s) rs-soroban-env/src/auth.rs \nLocation(s) require_auth_enforcing() \nConﬁrmed Fix At N/A \n_ In Soroban, contracts can request authorization for requests by invoking request auth on \nan address. If that address corresponds to a contract, the authorization module will invoke \n__ _ the check auth function of that module which is responsible for accepting or rejecting the \nrequested authorization. \nAs indicated in the documentation and related examples (such as this), it is usually frowned \n__ _ _ check auth upon for the function to call require auth on its own address, as this can lead to \ninﬁnite recursion. The concern here is that an attacker can abuse this frowned upon behavior to \ncause the algorithm to spent a disproportionate amount of time evaluating authorizations, very \nlittle of which is metered to the caller. \n__ _ In particular, suppose there is a contract whose implementation of simply calls check auth \n_ _ _ require auth on its own address. This will lead to repeated invocations of the require auth enforcing \nfunction, which has the following loop: \n___1fortrackerinself.tryborrowaccounttrackers(host)?.iter(){\n2 // Tracker can only be borrowed by the authorization manager itself. \n3 // The only scenario in which re-borrow might occur is when \n_ __ _ 4 // ‘require auth‘ is called within ‘ check auth‘ call. The tracker \n__ _ 5 // that called ‘ check auth‘ would be already borrowed in such \n6 // scenario. \n7 // We allow such call patterns in general, but we don’t allow using \n8 // tracker to verify auth for itself, i.e. we don’t allow something \n_____9//likeaddress.requireauth()->addresscontract.checkauth()\n_ 10 // ->address.require auth(). Thus we simply skip the trackers that \n11 // have already been borrowed. \n__12ifletOk(muttracker)=tracker.tryborrowmut(){\n13 // If tracker has already been used for this frame or the address \n14 // doesn’t match, just skip the tracker. \n_ 15 if !host.compare(&tracker.address, &address)?.is eq() { \n16 continue; \n17 } \n____18matchtracker.maybeauthorizeinvocation(host,function,!hasactivetracker)\n{ \n19 // If tracker doesn’t have a matching invocation, \n20 // just skip it (there could still be another \n21 // tracker that matches it). \n22 Ok(false) => continue, \n23 // Found a matching authorization. \n24 Ok(true) => return Ok(()), \n25 // Found a matching authorization, but another \n26 // requirement hasn’t been fulfilled (for \n27 // example, incorrect authentication or nonce). \n28 Err(e) => return Err(e), \nVeridise Audit Report: Stellar Soroban Core © 2023 Veridise Inc. \n\n14 4 Vulnerability Report \n29 } \n30 } \n31 } \nInformally, this loop iterates over each of the trackers (which are derived from the user provided \ninvocation signature tree) attempting to match the current call to one of the trackers. If the \nauthorization succeeds, the call is allowed as usual. If the call fails, we either continue or \npropagate an error if one has arisen. \n______checkcallIfthereisacalltorequireauthwithina,thecalltracker.maybeauthorizeinvocation\n_ _ _ _ (host, function, !has active tracker) could potentially call require auth enforcing again, \nwhich will again iterate through the trackers. Because each tracker is \"borrowed\" via that \n_ _ tracker.try borrow mut() , the same tracker cannot be used to match multiple calls to call to \n_ _ require auth at once. However, specially crafted trackers and a recursive call to require auth \n__ _ in can still lead to a long (but ﬁnite) sequence of calls which can eat up signiﬁcant check auth \nresources of Stellar nodes with little cost to the user. \nImpact An attacker could use this vulnerability to perform a denial of service attack. \n_ __ _ Why Invalid It turns out that a failed call to require auth in will return an Err . check auth \nAs shown in the loop above, Err s are propagated up, meaning the number of iterations of this \nloop will be linear in the number of trackers. Because constructing a large number of trackers is \ncostly to the attacker in other ways, this would be a costly attack to perform, and thus likely not \nworth it. \n© 2023 Veridise Inc. Veridise Audit Report: Stellar Soroban Core \n\n4.1 Detailed Description of Issues 15 \n4.1.3 V-SOR-VUL-003: Signature Replay Attack \nSeverity High Commit 16f4d7c \nType Data Validation Status Investigated \nFile(s) rs-stellar-xdr/src/next/generated.rs \nLocation(s) N/A \nConﬁrmed Fix At N/A \nSorobanAddressCredentials contains a signature expiration ledger and a nonce for each signature. \nThese credentials are only stored on the ledger as temporary values so they will be completely \nerased once they expire. As a result, if the signature itself isn’t hashed with an expiration date or \ntimestamp, there would be no way to know if an attacker reuses a previous signature that has \nexpired oﬀ of the ledger to replay a previous transaction on behalf of a user who had executed \nthat transaction in the past. \nImpact If this signature can be reused for a replay attack, this could allow attackers to steal \nfunds etc. If the signature cannot be reused, then there is no vulnerability. \nRecommendation Hash the signature with some timestamp for the transaction, so that if the \nsignature is reused later in time, it is possible to know that the signature has expired, even if the \nprevious nonce/expiration timestamp have been erased from the ledger. \nWhy Invalid Developers have indicated that the signature is already hashed with a timestamp \nthat would prevent such an attack. \nVeridise Audit Report: Stellar Soroban Core © 2023 Veridise Inc. \n\n16 4 Vulnerability Report","chunkIndex":7,"publishedAt":"2024-01-02T15:00:00.000Z","observedAt":"2026-09-24T11:03:05.341Z","docKind":null,"docVersionStatus":null,"auditor":"Veridise","protocol":"Stellar Soroban Core","severity":"critical","capStatus":null,"capProtocolVersion":null,"score":0.7189241647720337,"confidence":{"score":0.74,"label":"medium","relevance":0.64,"freshness":1,"authority":0.9,"ageDays":null}},{"id":"6a1516bc975750ee958a3bac","source":"audit","title":"Stellar Soroban Core — Veridise","section":"V-SOR-APP-VUL-003:","url":"https://stellarsecurityportal.com/report/42","content":"## V-SOR-APP-VUL-003:\n\n# DenialofService\n# During\n# Authorization\n\nSeverity Critical Commit 2674d86 \nType Denial of Service Status Investigated \nFile(s) rs-soroban-env/src/auth.rs \nLocation(s) require_auth_enforcing() \nConﬁrmed Fix At N/A \n_ In Soroban, contracts can request authorization for requests by invoking request auth on \nan address. If that address corresponds to a contract, the authorization module will invoke \n__ _ the check auth function of that module which is responsible for accepting or rejecting the \nrequested authorization. \nAs indicated in the documentation and related examples (such as this), it is usually frowned \n__ _ _ check auth upon for the function to call require auth on its own address, as this can lead to \ninﬁnite recursion. The concern here is that an attacker can abuse this frowned upon behavior to \ncause the algorithm to spent a disproportionate amount of time evaluating authorizations, very \nlittle of which is metered to the caller. \n__ _ In particular, suppose there is a contract whose implementation of simply calls check auth \n_ _ _ require auth on its own address. This will lead to repeated invocations of the require auth enforcing \nfunction, which has the following loop: \n___1fortrackerinself.tryborrowaccounttrackers(host)?.iter(){\n2 // Tracker can only be borrowed by the authorization manager itself. \n3 // The only scenario in which re-borrow might occur is when \n_ __ _ 4 // ‘require auth‘ is called within ‘ check auth‘ call. The tracker \n__ _ 5 // that called ‘ check auth‘ would be already borrowed in such \n6 // scenario. \n7 // We allow such call patterns in general, but we don’t allow using \n8 // tracker to verify auth for itself, i.e. we don’t allow something \n_____9//likeaddress.requireauth()->addresscontract.checkauth()\n_ 10 // ->address.require auth(). Thus we simply skip the trackers that \n11 // have already been borrowed. \n__12ifletOk(muttracker)=tracker.tryborrowmut(){\n13 // If tracker has already been used for this frame or the address \n14 // doesn’t match, just skip the tracker. \n_ 15 if !host.compare(&tracker.address, &address)?.is eq() { \n16 continue; \n17 } \n____18matchtracker.maybeauthorizeinvocation(host,function,!hasactivetracker)\n{ \n19 // If tracker doesn’t have a matching invocation, \n20 // just skip it (there could still be another \n21 // tracker that matches it). \n22 Ok(false) => continue, \n23 // Found a matching authorization. \n24 Ok(true) => return Ok(()), \n25 // Found a matching authorization, but another \n26 // requirement hasn’t been fulfilled (for \n27 // example, incorrect authentication or nonce). \n28 Err(e) => return Err(e), \n© 2023 Veridise Inc. Veridise Audit Report: Stellar Soroban Core \n\nA.2 Invalid Issues 49 \n29 } \n30 } \n31 } \nInformally, this loop iterates over each of the trackers (which are derived from the user provided \ninvocation signature tree) attempting to match the current call to one of the trackers. If the \nauthorization succeeds, the call is allowed as usual. If the call fails, we either continue or \npropagate an error if one has arisen. \n______checkcallIfthereisacalltorequireauthwithina,thecalltracker.maybeauthorizeinvocation\n_ _ _ _ (host, function, !has active tracker) could potentially call require auth enforcing again, \nwhich will again iterate through the trackers. Because each tracker is \"borrowed\" via that \n_ _ tracker.try borrow mut() , the same tracker cannot be used to match multiple calls to call to \n_ _ require auth at once. However, specially crafted trackers and a recursive call to require auth \n__ _ in can still lead to a long (but ﬁnite) sequence of calls which can eat up signiﬁcant check auth \nresources of Stellar nodes with little cost to the user. \nImpact An attacker could use this vulnerability to perform a denial of service attack. \n_ __ _ Why Invalid It turns out that a failed call to require auth in will return an Err . check auth \nAs shown in the loop above, Err s are propagated up, meaning the number of iterations of this \nloop will be linear in the number of trackers. Because constructing a large number of trackers is \ncostly to the attacker in other ways, this would be a costly attack to perform, and thus likely not \nworth it. \nVeridise Audit Report: Stellar Soroban Core © 2023 Veridise Inc. \n\n50 A Appendix \nA.2.3 V-SOR-APP-VUL-004: Signature Replay Attack \nSeverity High Commit 16f4d7c \nType Data Validation Status Investigated \nFile(s) rs-stellar-xdr/src/next/generated.rs \nLocation(s) N/A \nConﬁrmed Fix At N/A \nSorobanAddressCredentials contains a signature expiration ledger and a nonce for each signature. \nThese credentials are only stored on the ledger as temporary values so they will be completely \nerased once they expire. As a result, if the signature itself isn’t hashed with an expiration date or \ntimestamp, there would be no way to know if an attacker reuses a previous signature that has \nexpired oﬀ of the ledger to replay a previous transaction on behalf of a user who had executed \nthat transaction in the past. \nImpact If this signature can be reused for a replay attack, this could allow attackers to steal \nfunds etc. If the signature cannot be reused, then there is no vulnerability. \nRecommendation Hash the signature with some timestamp for the transaction, so that if the \nsignature is reused later in time, it is possible to know that the signature has expired, even if the \nprevious nonce/expiration timestamp have been erased from the ledger. \nWhy Invalid Developers have indicated that the signature is already hashed with a timestamp \nthat would prevent such an attack. \n© 2023 Veridise Inc. Veridise Audit Report: Stellar Soroban Core \n\nA.2 Invalid Issues 51 \n# A.2.4","chunkIndex":16,"publishedAt":"2025-09-26T15:00:00.000Z","observedAt":"2026-09-24T11:03:05.341Z","docKind":null,"docVersionStatus":null,"auditor":"Veridise","protocol":"Stellar Soroban Core","severity":"critical","capStatus":null,"capProtocolVersion":null,"score":0.718776524066925,"confidence":{"score":0.74,"label":"medium","relevance":0.64,"freshness":1,"authority":0.9,"ageDays":null}},{"id":"6a151659d5ac3338bbd50c82","source":"dev-docs","title":"Signing Soroban contract invocations","section":null,"url":"https://developers.stellar.org/docs/build/guides/transactions/signing-soroban-invocations","content":"# Signing Soroban contract invocations\n\n- \n- How-To Guides\n- Transactions\n- Signing Soroban contract invocations\n\n \n\n# Signing Soroban contract invocations\nWhen invoking Soroban smart contracts that require authorization, there are two distinct signing approaches. Understanding when to use each method is essential for building powerful applications that interact with smart contracts.","chunkIndex":0,"publishedAt":"2026-06-17T00:00:00.000Z","observedAt":"2026-09-24T11:02:01.940Z","docKind":null,"docVersionStatus":null,"auditor":null,"protocol":null,"severity":null,"capStatus":null,"capProtocolVersion":null,"score":0.7128541469573975,"confidence":{"score":0.74,"label":"medium","relevance":0.62,"freshness":1,"authority":0.95,"ageDays":null}},{"id":"6a500bb2ab3ef06c37b2f127","source":"dev-docs","title":"Advanced Smart Contract Concepts with Solidity and Rust","section":"Solidity to Soroban: Common Concepts and Best Practices​","url":"https://developers.stellar.org/docs/learn/migrate/evm/solidity-and-rust-advanced-concepts","content":"## Solidity to Soroban: Common Concepts and Best Practices​\n\n function transfer(address to, uint256 amount) public returns (bool) {\n require(allowances[msg.sender][to] >= amount, \"Not enough allowance\");\n require(isAuthorized[to] == true, \"Not authorized\");\n balances[msg.sender] -= amount;\n balances[to] += amount;\n return true;\n }\n}\n\nThe approve function allows the token holder to authorize spender to spend amount tokens on their behalf. The transfer function then checks if the spender is authorized to spend the amount of tokens requested by the token holder. If so, the transfer is executed.\n\nThese Solidity examples illustrate some common authorization patterns used in Ethereum smart contracts. Soroban provides alternative approaches to achieve similar functionality, leveraging core functionality derived right from the soroban SDK.\n\nSoroban​\nSoroban&#x27;s design principles prioritize flexibility, security, and testability, which have led to differences in how authorization is handled compared to Solidity.\n\nSoroban provides built-in functions such as require_auth and require_auth_for_args through the Address struct. These functions help enforce authorization rules within contracts. During on-chain execution, the Soroban host performs the necessary authentication, including verifying signatures and ensuring replay prevention. This alleviates the burden of authentication from the contracts themselves, promoting security and reducing potential vulnerabilities.\n\nHere is an example of a smart contract that illustrates how authorization is handled in Soroban:\n\n#![no_std]\nuse soroban_sdk::{contractimpl, testutils::Address as _, Address, Symbol, Env, IntoVal};\n\n#[contract]\npub struct Contract;\n\n#[contractimpl]\nimpl Contract {\n pub fn transfer(env: Env, address: Address, amount: i128) {\n address.require_auth();\n }\n pub fn transfer2(env: Env, address: Address, amount: i128) {\n address.require_auth_for_args((amount / 2,).into_val(&env));\n }\n}\n\nIn this example, we have a Soroban contract that includes two public functions: transfer and transfer2, both of which involve authorization checks.\n\nInside the Transfer function, the require_auth method is invoked on the address object. This method ensures that the caller of the contract has the necessary authorization to execute the transfer.\n\nThe transfer2 function follows a similar pattern but uses the require_auth_for_args method instead. It takes the same parameters as transfer but provides a tuple (amount / 2,) as the argument to require_auth_for_args. This method verifies that the caller has authorized the contract invocation with the specific arguments.\n\nBy utilizing these authorization methods provided by the Address object from the Soroban Rust SDK, the contract enforces that only authorized callers can perform the transfers. This approach enhances the security of the contract by ensuring that sensitive operations can only be executed by authorized parties.\n\nSoroban&#x27;s approach to authorization in this example offers several advantages over Solidity&#x27;s model of ERC20 by eliminating the need for separate approval management. Instead, authorization checks can be directly incorporated into any Soroban function. This simplifies the contract codebase and reduces the complexity associated with managing separate approval states.\n\nSoroban authorization provides Contract-level Authorization, Account Abstraction Functionality, and more advanced Authorization checks. To learn more about these advantages, visit the Authorization section of the documentation.","chunkIndex":8,"publishedAt":"2025-08-04T00:00:00.000Z","observedAt":"2026-09-24T11:02:01.940Z","docKind":null,"docVersionStatus":null,"auditor":null,"protocol":null,"severity":null,"capStatus":null,"capProtocolVersion":null,"score":0.7318080067634583,"confidence":{"score":0.73,"label":"medium","relevance":0.61,"freshness":1,"authority":0.95,"ageDays":null}},{"id":"6a500b91ab3ef06c37b2ef77","source":"dev-docs","title":"Invoke and deploy smart contracts with the InvokeHostFunctionOp operation","section":"XDR Usage​","url":"https://developers.stellar.org/docs/learn/fundamentals/contract-development/contract-interactions/stellar-transaction","content":"## XDR Usage​\n\n- SOROBAN_CREDENTIALS_SOURCE_ACCOUNT - this simply uses the signature of the transaction (or operation, if any) source account and hence doesn&#x27;t require any additional payload.\n\n- SOROBAN_CREDENTIALS_ADDRESS - contains SorobanAddressCredentials with the following structure:\nstruct SorobanAddressCredentials\n{\n SCAddress address;\n int64 nonce;\n uint32 signatureExpirationLedger;\n SCVal signature;\n};\n\nThe fields of this structure have the following semantics:\n\n- When address is the address that authorizes invocation.\n\n- signatureExpirationLedger the ledger sequence number on which the signature expires. Signature is still considered valid on signatureExpirationLedger, but it is no longer valid on signatureExpirationLedger + 1. It is recommended to keep this as small as viable, as it makes the transaction cheaper.\n\n- nonce is an arbitrary value that is unique for all the signatures performed by address until signatureExpirationLedger. A good approach to generating this is to just use a random value.\n\n- signature is a structure containing the signature (or multiple signatures) that signed the 32-byte, SHA-256 hash of the ENVELOPE_TYPE_SOROBAN_AUTHORIZATION preimage (XDR). The signature structure is defined by the account contract corresponding to the Address (see below for the Stellar account signature structure).\n\nSorobanAuthorizedInvocation defines a node in the authorized invocation tree:\n\nstruct SorobanAuthorizedInvocation\n{\n SorobanAuthorizedFunction function;\n SorobanAuthorizedInvocation subInvocations<>;\n};\n\nunion SorobanAuthorizedFunction switch (SorobanAuthorizedFunctionType type)\n{\ncase SOROBAN_AUTHORIZED_FUNCTION_TYPE_CONTRACT_FN:\n SorobanAuthorizedContractFunction contractFn;\ncase SOROBAN_AUTHORIZED_FUNCTION_TYPE_CREATE_CONTRACT_HOST_FN:\n CreateContractArgs createContractHostFn;\n};\n\nstruct SorobanAuthorizedContractFunction\n{\n SCAddress contractAddress;\n SCSymbol functionName;\n SCVec args;\n};\n\nSorobanAuthorizedInvocation consists of the function that is being authorized (either contract function or a host function) and the authorized sub-invocations that function performs (if any).\n\nSorobanAuthorizedFunction has two variants:\n\n- SOROBAN_AUTHORIZED_FUNCTION_TYPE_CONTRACT_FN is a contract function that includes the address of the contract, name of the function being invoked, and arguments of the require_auth/require_auth_for_args call performed on behalf of the address. Note, that if require_auth[_for_args] wasn&#x27;t called, there shouldn&#x27;t be a SorobanAuthorizedInvocation entry in the transaction.\n\n- SOROBAN_AUTHORIZED_FUNCTION_TYPE_CREATE_CONTRACT_HOST_FN is authorization for HOST_FUNCTION_TYPE_CREATE_CONTRACT or for create_contract host function called from a contract. It only contains the CreateContractArgs XDR structure corresponding to the created contract.\n\nBuilding SorobanAuthorizedInvocation trees may be simplified by using the recording auth mode in Soroban&#x27;s simulateTransaction mechanism (see the docs for more details).\n\nStellar Account Signatures​\nsignatureArgs format is user-defined for the custom accounts, but it is protocol-defined for the Stellar accounts.\n\nThe signatures for the Stellar account are a vector of the following Soroban structures in the Soroban SDK format:\n\n#[contracttype]\npub struct AccountEd25519Signature {\n pub public_key: BytesN<32>,\n pub signature: BytesN<64>,\n}\n\nJavaScript Usage​\nThere are a couple of helpful methods in the SDK to make dealing with authorization easier:\n\n- Once you&#x27;ve gotten the authorization entries from simulateTransaction, you can use the authorizeEntry helper to \"fill out\" the empty entry accordingly. You will, of course, need the appropriate signer for each of the entries if you are in a multi-party situation.\n\nconst signedEntries = simTx.auth.map(async (entry) =>\n // In this case, you can authorize by signing the transaction with the\n // corresponding source account.\n entry.switch() ===\n xdr.SorobanCredentialsType.sorobanCredentialsSourceAccount()\n ? entry\n : await authorizeEntry(\n entry,\n // The `signer` here will be unique for each entry, perhaps reaching out\n // to a separate entity.\n signer,\n currentLedger + 1000,\n Networks.TESTNET,\n ),\n);\n\n- If you, instead, want to build an authorization entry from scratch rather than relying on simulation, you can use authorizeInvocation, which will build the structure with the appropriate fields.\n\n### Transaction resources​\n\nEvery Soroban transaction has to have a SorobanTransactionData transaction extension populated. This is needed to compute the Soroban resource fee.\n\nThe Soroban transaction data is defined as follows:\n\nstruct SorobanResources\n{\n // The ledger footprint of the transaction.\n LedgerFootprint footprint;\n // The maximum number of instructions this transaction can use\n uint32 instructions;\n\n // The maximum number of bytes this transaction can read from disk backed entries\n uint32 diskReadBytes;\n // The maximum number of bytes this transaction can write to ledger\n uint32 writeBytes;\n};\n\nstruct SorobanResourcesExtV0\n{\n // Vector of indices representing what Soroban\n // entries in the footprint are archived, based on the\n // order of keys provided in the readWrite footprint.\n uint32 archivedSorobanEntries<>;\n};\n\nstruct SorobanTransactionData\n{\n union switch (int v)\n {\n case 0:\n void;\n case 1:\n SorobanResourcesExtV0 resourceExt;\n } ext;\n SorobanResources resources;\n // Amount of the transaction `fee` allocated to the Soroban resource fees.\n int64 resourceFee;\n};\n\nThis data comprises the Soroban resources and the resourceFee. The resourceFee is the portion of the transaction fee allocated to Soroban resource fees. It has a non-refundable part (fees for instructions, ledger I/O, and transaction size) and a refundable part that is charged based on actual consumption of refundable resources: the contract events emitted by the transaction, the return value of the host function invocation, and the ledger space rent.","chunkIndex":4,"publishedAt":"2026-07-30T00:00:00.000Z","observedAt":"2026-09-24T11:02:01.940Z","docKind":null,"docVersionStatus":null,"auditor":null,"protocol":null,"severity":null,"capStatus":null,"capProtocolVersion":null,"score":0.723287045955658,"confidence":{"score":0.72,"label":"medium","relevance":0.58,"freshness":1,"authority":0.95,"ageDays":null}}]}