Skip to content

🫴 Refresh Claimable Balances guide - #2752

Draft
JFWooten4 wants to merge 6 commits into
stellar:mainfrom
JFWooten4:refresh-claimable-balances
Draft

🫴 Refresh Claimable Balances guide#2752
JFWooten4 wants to merge 6 commits into
stellar:mainfrom
JFWooten4:refresh-claimable-balances

Conversation

@JFWooten4

Copy link
Copy Markdown
Contributor

from #723

I had the narrative cemented for a while before #1784 and made some comments regarding style choices in #723 (comment).

Copilot AI balanced review requested due to automatic review settings August 14, 2026 18:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refreshes the Claimable Balances guide, but blocking accuracy, security, and compilation issues remain across the SDK examples.

Changes:

  • Reorganizes the guide around setup, retrieval, and claiming.
  • Adds Python, JavaScript, Java, and Go examples.
  • Expands balance-ID and predicate explanations.

Recommendation: NEEDS-CHANGES — fix the broken examples, exposed secret seeds, and inaccurate identifier/API guidance.

Suppressed comments (2)

docs/build/guides/transactions/claimable-balances.mdx:264

  • This Java example embeds a valid secret seed and relies on that account remaining funded. Generate and fund a disposable Testnet keypair instead of publishing live key material.
    KeyPair aKeypair = KeyPair.fromSecretSeed(
      "SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4"
    );

docs/build/guides/transactions/claimable-balances.mdx:330

  • This Go example also publishes a valid secret seed and depends on a persistent funded account. Generate and fund a disposable Testnet account instead.
  aKeys := keypair.MustParseFull(
    "SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4"
  )

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

- `AND[ NOT( BEFORE_ABSOLUTE_TIME(X) )`, `BEFORE_ABSOLUTE_TIME(Y) ]`: Can claim between X and Y Unix timestamps (given X < Y).
- `OR[ BEFORE_ABSOLUTE_TIME(X)`, `NOT( BEFORE_ABSOLUTE_TIME(Y) ) ]`: Can claim outside X and Y Unix timestamps (given X < Y).
- **`ClaimableBalanceID`**: ClaimableBalanceID is a union with one possible type (`CLAIMABLE_BALANCE_ID_TYPE_V0`). This one type's only item is a SHA-256 hash of the source account, sequence number, and operation index in an XDR discriminator unit. Its `StrKey` representation is a 58-character string beginning with `B`, such as `BAAD6DBUX6J22DMZOHIEZTEQ64CVCHEDRKWZONFEUL5Q26QD7R76RGR4TU`.
- **`ClientBalanceID`**: Hex of `ClaimableBalanceID` returned after a successful `CreateClaimableBalance` operation. The `ClaimClaimableBalance` operation uses this (with zero-padding to 72 characters) to claim the `ClaimableBalanceEntry`.

### Claim Claimable Balance

For basic parameters, see the Claim Claimable Balance entry in our [List of Operations section](../../../learn/fundamentals/transactions/list-of-operations#claim-claimable-balance).
[This operation](../../../learn/fundamentals/transactions/list-of-operations.mdx#clawback-claimable-balance) claws back a claimable balance, returning the asset to the issuer account, burning it. You must claw back the entire claimable balance, not just part of it. Once a claimable balance has been claimed, use the regular clawback operation to claw it back.

Clawback claimable balances require the claimable balance ID.
You clawback a claimable balances with its `ClientBalanceID`.
Each of these accounts can only claim the balance under unique conditions. $\mathcal{B}$ has a full minute to claim the balance before $\mathcal{A}$ can reclaim the balance back for itself.

**Note:** there is no recovery mechanism for a claimable balance in general — if none of the predicates can be fulfilled, the balance cannot be recovered. The reclaim example below acts as a safety net for this situation.
The reclaim logic acts as a safety net if none of the predicates can be fulfilled. Otherwise the transaction could render the asset unusable forever.
Comment on lines +131 to +140
var txResult xdr.TransactionResult
err := xdr.SafeUnmarshalBase64(resp.ResultXDR, &txResult)
if err != nil {
return "", err
}

if results, ok := txResult.OperationResults(); ok && len(results) > 0 {
operationResult := results[0].MustTr().CreateClaimableBalanceResult
return xdr.MarshalHex(operationResult.BalanceId)
}
Comment on lines +446 to +450
// We look at the first result since our first (and only) operation
// in the transaction was the CreateClaimableBalanceOp.
let operationResult = results[0].value().createClaimableBalanceResult();
let clientBalanceID = operationResult.balanceId().toXDR("hex");
console.log("Balance ID (2):", clientBalanceID);
Comment on lines +507 to +511
String clientBalanceID = tx.getClaimableBalanceId(0)
System.out.println("Balance ID (1): " + clientBalanceID);

// Method 2: Suppose txResponse comes from the transaction submission above.
String txResponseResultXdr = txResponse.getResultXdr().get();
Comment on lines +545 to +550
// Method 1: Suppose `tx` comes from the transaction built above.
// Notice that this can be done *before* submission.
// Use zero for `CreateClaimableBalance` first op.
clientBalanceID, err := tx.ClaimableBalanceID(0)
check(err)
fmt.Println("Balance ID (1):", clientBalanceID)
Comment on lines +657 to +661
.addOperation(
sdk.Operation.claimClaimableBalance({
balanceId: clientBalanceID,
});
)
Comment on lines +674 to +678
Transaction tx = new Transaction.Builder(aAccount, Network.TESTNET)
.addOperation(
new ClaimClaimableBalanceOperation.Builder(clientBalanceID).build();
)
.setBaseFee(tx.MIN_BASE_FEE)
@JFWooten4
JFWooten4 marked this pull request as draft August 18, 2026 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants