diff --git a/content/docs/glossary/sponsored-reserves.mdx b/content/docs/glossary/sponsored-reserves.mdx
index 69142360c..a785ea7d7 100644
--- a/content/docs/glossary/sponsored-reserves.mdx
+++ b/content/docs/glossary/sponsored-reserves.mdx
@@ -3,6 +3,8 @@ title: Sponsored Reserves
order:
---
+import { CodeExample } from "components/CodeExample";
+
Protocol 14 introduces operations that allow an account to pay the base reserves for another account. This is done by using the [Begin Sponsoring Future Reserves](../start/list-of-operations.mdx#begin-sponsoring-future-reserves) and [End Sponsoring Future Reserves](../start/list-of-operations.mdx#end-sponsoring-future-reserves) operations.
The sponsoring account establishes the is-sponsoring-future-reserves-for relationship, and the sponsored account terminates it. While this relationship exists, reserve requirements that would normally accumulate on the sponsored account will now accumulate on the sponsoring account. Both operations must appear in a single transaction, which guarantees that both the sponsoring and sponsored accounts agree to every sponsorship.
@@ -33,35 +35,6 @@ Anything that increases the minimum balance can be sponsored (Accounts, Offers,
At the end of any transaction, there must be no ongoing is-sponsoring-future-reserves-for relationships. This is why these two operations must be used together in a single transaction.
-### Simple Example
-
-In the example below, `A` is sponsoring a trustline for `B`. Notice how the `CHANGE_TRUST` operation is sandwiched between the begin and end sponsoring operations.
-
-```
-sourceAccount: B
-operations[0]:
- sourceAccount: A
- body:
- type: BEGIN_SPONSORING_FUTURE_RESERVES
- sponsoredID: B
-operations[1]:
- sourceAccount: B
- body:
- type: CHANGE_TRUST
- line: X
- limit: INT64_MAX
-operations[2]:
- sourceAccount: B
- body:
- type: END_SPONSORING_FUTURE_RESERVES
-```
-
-#### Other Examples
-
-https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#example-sponsoring-account-creation
-
-https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#example-two-trust-lines-with-different-sponsors
-
### Revoke Sponsorship
[Revoke Sponsorship](../start/list-of-operations.mdx#revoke-sponsorship) is the third and final operation relevant to sponsorships. It allows the sponsoring account to remove/transfer sponsorships of existing ledgerEntries and signers. If the ledgerEntry/signer is not sponsored, the owner of the ledgerEntry/signer can establish a sponsorship if it is the beneficiary of a is-sponsoring-future-reserves-for relationship.
@@ -85,8 +58,252 @@ See [Revoke Sponsorship](../start/list-of-operations.mdx#revoke-sponsorship) for
The logic above does not detail any of the error cases, which are specified [here](../start/list-of-operations.mdx#revoke-sponsorship).
-#### Examples
+## Examples
+Each example builds on itself, referencing variables from previous snippets. We'll demonstrate a few different things you can do with sponsoring:
+ - Sponsor creation of a trustline for another account.
+ - Sponsor **two** trustlines for an account via two *different* sponsors.
+ - Transfer sponsorship responsibility from one account to another.
+ - Revoke sponsorship by an account entirely.
+
+(For brevity, we'll assume the existence of a `SignAndSend(...)` method (defined [below](#footnote)) which will creates and submits a transaction with the proper parameters and error-checking.
+
+### Preamble
+We'll start by including the boilerplate of account and asset creation.
+
+
+
+```go
+package main
+
+import (
+ "fmt"
+ "net/http"
+
+ sdk "github.com/stellar/go/clients/horizonclient"
+ "github.com/stellar/go/keypair"
+ "github.com/stellar/go/network"
+ protocol "github.com/stellar/go/protocols/horizon"
+ "github.com/stellar/go/txnbuild"
+)
+
+func main() {
+ client := sdk.DefaultTestNetClient
+
+ // Both S1 and S2 will be sponsors for A at various points in time.
+ S1, A, S2 := keypair.MustRandom(), keypair.MustRandom(), keypair.MustRandom()
+ addressA := A.Address()
+
+ for _, pair := range []*keypair.Full{S1, A, S2} {
+ resp, err := http.Get("https://friendbot.stellar.org/?addr=" + pair.Address())
+ check(err)
+ resp.Body.Close()
+ fmt.Println("Funded", pair.Address())
+ }
+
+ // Load the corresponding account for both A and C.
+ s1Account, err := client.AccountDetail(sdk.AccountRequest{AccountID: S1.Address()})
+ check(err)
+ aAccount, err := client.AccountDetail(sdk.AccountRequest{AccountID: addressA})
+ check(err)
+ s2Account, err := client.AccountDetail(sdk.AccountRequest{AccountID: S2.Address()})
+ check(err)
+
+ // Arbitrary assets to sponsor trustlines for. Let's assume they make sense.
+ assets := []txnbuild.CreditAsset{
+ txnbuild.CreditAsset{Code: "ABCD", Issuer: S1.Address()},
+ txnbuild.CreditAsset{Code: "EFGH", Issuer: S1.Address()},
+ txnbuild.CreditAsset{Code: "IJKL", Issuer: S2.Address()},
+ }
+
+ // ...
+```
+
+
+
+
+### Sponsoring a Trustline
+Now, let's sponsor trustlines for Account A. Notice how the `CHANGE_TRUST` operation is sandwiched between the begin and end sponsoring operations and that all relevant accounts need to sign the transaction.
+
+
+
+```go
+ //
+ // 1. S1 will sponsor a trustline for Account A.
+ //
+ sponsorTrustline := []txnbuild.Operation{
+ &txnbuild.BeginSponsoringFutureReserves{
+ SourceAccount: &s1Account,
+ SponsoredID: addressA,
+ },
+ &txnbuild.ChangeTrust{
+ SourceAccount: &aAccount,
+ Line: &assets[0],
+ Limit: txnbuild.MaxTrustlineLimit,
+ },
+ &txnbuild.EndSponsoringFutureReserves{},
+ }
+
+ // Note that while A can submit this transaction, both sign it.
+ SignAndSend(client, &aAccount, []*keypair.Full{S1, A}, sponsorTrustline...)
+ fmt.Println("Sponsored a trustline of", A.Address())
+
+ //
+ // 2. Both S1 and S2 sponsor trustlines for Account A for different assets.
+ //
+ sponsorTrustline = []txnbuild.Operation{
+ &txnbuild.BeginSponsoringFutureReserves{
+ SourceAccount: &s1Account,
+ SponsoredID: addressA,
+ },
+ &txnbuild.ChangeTrust{
+ Line: &assets[1],
+ Limit: txnbuild.MaxTrustlineLimit,
+ },
+ &txnbuild.EndSponsoringFutureReserves{},
-https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#example-revoke-sponsorship
+ &txnbuild.BeginSponsoringFutureReserves{
+ SourceAccount: &s2Account,
+ SponsoredID: addressA,
+ },
+ &txnbuild.ChangeTrust{
+ Line: &assets[2],
+ Limit: txnbuild.MaxTrustlineLimit,
+ },
+ &txnbuild.EndSponsoringFutureReserves{},
+ }
+
+ // Note that all 3 accounts must approve/sign this transaction.
+ SignAndSend(client, &aAccount, []*keypair.Full{S1, S2, A}, sponsorTrustline...)
+ fmt.Println("Sponsored two trustlines of", A.Address())
+```
+
+
+
+
+### Transferring Sponsorship
+Suppose that now Signer 1 wants to transfer responsibility of sponsoring reserves for the trustline to Sponsor 2. This is accomplished by sandwiching the transfer between the `BEGIN/END_SPONSORING_FUTURE_RESERVES` operations. Both of the participants must sign the transaction, though either can submit it.
+
+
+
+```go
+ //
+ // 3. Transfer sponsorship of B's second trustline from S1 to S2.
+ //
+ transferOps := []txnbuild.Operation{
+ &txnbuild.BeginSponsoringFutureReserves{
+ SourceAccount: &s2Account,
+ SponsoredID: S1.Address(),
+ },
+ &txnbuild.RevokeSponsorship{
+ SourceAccount: &s1Account,
+ SponsorshipType: txnbuild.RevokeSponsorshipTypeTrustLine,
+ Account: &addressA,
+ TrustLine: &txnbuild.TrustLineID{
+ Account: addressA,
+ Asset: assets[1],
+ },
+ },
+ &txnbuild.EndSponsoringFutureReserves{},
+ }
+
+ // Notice that while the old sponsor *sends* the transaction, both sponsors
+ // must *approve* the transfer.
+ SignAndSend(client, &s1Account, []*keypair.Full{S1, S2}, transferOps...)
+ fmt.Println("Transferred sponsorship for", A.Address())
+```
+
+
+
+At this point, Signer 1 is only sponsoring the first asset (arbitrarily coded as `ABCD`), while Signer 2 is sponsoring the other two assets.
+
+### Sponsorship Revocation
+Finally, we can demonstrate complete revocation of sponsorships. Below, Signer 2 removes themselves from all responsibility over the two asset trustlines. Notice that Account A is not involved at all, since revocation should be performable purely at the sponsor's discretion.
+
+
+
+```go
+ //
+ // 4. S2 revokes sponsorship of B's trustlines entirely.
+ //
+ revokeOps := []txnbuild.Operation{
+ &txnbuild.RevokeSponsorship{
+ SponsorshipType: txnbuild.RevokeSponsorshipTypeTrustLine,
+ Account: &addressA,
+ TrustLine: &txnbuild.TrustLineID{
+ Account: addressA,
+ Asset: assets[1],
+ },
+ },
+ &txnbuild.RevokeSponsorship{
+ SponsorshipType: txnbuild.RevokeSponsorshipTypeTrustLine,
+ Account: &addressA,
+ TrustLine: &txnbuild.TrustLineID{
+ Account: addressA,
+ Asset: assets[2],
+ },
+ },
+ }
+
+ SignAndSend(client, &s2Account, []*keypair.Full{S2}, revokeOps...)
+ fmt.Println("Revoked sponsorship for", A.Address())
+} // ends main()
+```
+
+
+
+
+### Other Examples
+If you'd like other examples, or want to view a more-generic pseudocode breakdown of these sponsorship scenarios, you can refer to [CAP-0033](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#example-revoke-sponsorship) directly.
+
+
+### Footnote
+An implementation of `SignAndSend` might look something like this:
+
+
+
+```go
+// Builds a transaction containing `operations...`, signed (by `signers`), and
+// submitted using the given `client` on behalf of `account`.
+func SignAndSend(
+ client *sdk.Client,
+ account txnbuild.Account,
+ signers []*keypair.Full,
+ operations ...txnbuild.Operation,
+) protocol.Transaction {
+ // Build, sign, and submit the transaction
+ tx, err := txnbuild.NewTransaction(
+ txnbuild.TransactionParams{
+ SourceAccount: account,
+ IncrementSequenceNum: true,
+ BaseFee: txnbuild.MinBaseFee,
+ Timebounds: txnbuild.NewInfiniteTimeout(),
+ Operations: operations,
+ },
+ )
+ check(err)
+
+ for _, signer := range signers {
+ tx, err = tx.Sign(network.TestNetworkPassphrase, signer)
+ check(err)
+ }
+
+ txResp, err := client.SubmitTransaction(tx)
+ if err != nil {
+ if prob := sdk.GetError(err); prob != nil {
+ fmt.Printf(" problem: %s\n", prob.Problem.Detail)
+ fmt.Printf(" extras: %s\n", prob.Problem.Extras["result_codes"])
+ }
+ check(err)
+ }
+
+ return txResp
+}
+
+func check(err error) {
+ if err != nil {
+ panic(err)
+ }
+}
+```
-https://github.com/stellar/stellar-protocol/blob/master/core/cap-0033.md#example-transfer-sponsorship
+