From 6f9f86b00a8a7dcdd2bf1aa5590fde28458dc6da Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 9 Sep 2026 06:47:53 +0000 Subject: [PATCH 1/5] rename token doc's approve arg to live_until_ledger --- .../example-contracts/tokens.mdx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/build/smart-contracts/example-contracts/tokens.mdx b/docs/build/smart-contracts/example-contracts/tokens.mdx index 44d652810..0bf34c672 100644 --- a/docs/build/smart-contracts/example-contracts/tokens.mdx +++ b/docs/build/smart-contracts/example-contracts/tokens.mdx @@ -129,10 +129,10 @@ use soroban_sdk::{Address, Env}; pub fn read_allowance(e: &Env, from: Address, spender: Address) -> AllowanceValue { let key = DataKey::Allowance(AllowanceDataKey { from, spender }); if let Some(allowance) = e.storage().temporary().get::<_, AllowanceValue>(&key) { - if allowance.expiration_ledger < e.ledger().sequence() { + if allowance.live_until_ledger < e.ledger().sequence() { AllowanceValue { amount: 0, - expiration_ledger: allowance.expiration_ledger, + live_until_ledger: allowance.live_until_ledger, } } else { allowance @@ -140,7 +140,7 @@ pub fn read_allowance(e: &Env, from: Address, spender: Address) -> AllowanceValu } else { AllowanceValue { amount: 0, - expiration_ledger: 0, + live_until_ledger: 0, } } } @@ -150,22 +150,22 @@ pub fn write_allowance( from: Address, spender: Address, amount: i128, - expiration_ledger: u32, + live_until_ledger: u32, ) { let allowance = AllowanceValue { amount, - expiration_ledger, + live_until_ledger, }; - if amount > 0 && expiration_ledger < e.ledger().sequence() { - panic!("expiration_ledger is less than ledger seq when amount > 0") + if amount > 0 && live_until_ledger < e.ledger().sequence() { + panic!("live_until_ledger is less than ledger seq when amount > 0") } let key = DataKey::Allowance(AllowanceDataKey { from, spender }); e.storage().temporary().set(&key.clone(), &allowance); if amount > 0 { - let live_for = expiration_ledger + let live_for = live_until_ledger .checked_sub(e.ledger().sequence()) .unwrap(); @@ -184,7 +184,7 @@ pub fn spend_allowance(e: &Env, from: Address, spender: Address, amount: i128) { from, spender, allowance.amount - amount, - allowance.expiration_ledger, + allowance.live_until_ledger, ); } } @@ -328,7 +328,7 @@ impl TokenInterface for Token { read_allowance(&e, from, spender).amount } - fn approve(e: Env, from: Address, spender: Address, amount: i128, expiration_ledger: u32) { + fn approve(e: Env, from: Address, spender: Address, amount: i128, live_until_ledger: u32) { from.require_auth(); check_nonnegative_amount(amount); @@ -337,12 +337,14 @@ impl TokenInterface for Token { .instance() .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); - write_allowance(&e, from.clone(), spender.clone(), amount, expiration_ledger); + write_allowance(&e, from.clone(), spender.clone(), amount, live_until_ledger); + // The event's `expiration_ledger` data field name is unchanged to + // preserve on-chain event compatibility (soroban-token-sdk::events::Approve). events::Approve { from, spender, amount, - expiration_ledger, + expiration_ledger: live_until_ledger, } .publish(&e); } @@ -489,7 +491,7 @@ pub struct AllowanceDataKey { #[contracttype] pub struct AllowanceValue { pub amount: i128, - pub expiration_ledger: u32, + pub live_until_ledger: u32, } #[derive(Clone)] From 1fae38ca72a6ba44ac3b94da9a3607e1367fab3c Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 10 Sep 2026 07:20:42 +1000 Subject: [PATCH 2/5] Update tokens.mdx --- docs/build/smart-contracts/example-contracts/tokens.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/build/smart-contracts/example-contracts/tokens.mdx b/docs/build/smart-contracts/example-contracts/tokens.mdx index 0bf34c672..5982589e0 100644 --- a/docs/build/smart-contracts/example-contracts/tokens.mdx +++ b/docs/build/smart-contracts/example-contracts/tokens.mdx @@ -338,8 +338,6 @@ impl TokenInterface for Token { .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); write_allowance(&e, from.clone(), spender.clone(), amount, live_until_ledger); - // The event's `expiration_ledger` data field name is unchanged to - // preserve on-chain event compatibility (soroban-token-sdk::events::Approve). events::Approve { from, spender, From 2d77a27a59f20c5a5cf4beee727eac5b3942f5f9 Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 10 Sep 2026 07:22:39 +1000 Subject: [PATCH 3/5] Update tokens.mdx --- .../build/smart-contracts/example-contracts/tokens.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/build/smart-contracts/example-contracts/tokens.mdx b/docs/build/smart-contracts/example-contracts/tokens.mdx index 5982589e0..421a4136a 100644 --- a/docs/build/smart-contracts/example-contracts/tokens.mdx +++ b/docs/build/smart-contracts/example-contracts/tokens.mdx @@ -35,7 +35,7 @@ This example shows how to build a token from scratch using only the `soroban-sdk [open-in-github-codespaces]: https://github.com/codespaces/new?repo=stellar/soroban-examples&editor=web [open-in-code-anywhere]: https://app.codeanywhere.com/#https://github.com/stellar/soroban-examples -[token example]: https://github.com/stellar/soroban-examples/tree/v23.0.0/token +[token example]: https://github.com/stellar/soroban-examples/tree/main/token [token interface]: ../../../tokens/token-interface.mdx :::info[Whisk Changes] @@ -46,10 +46,10 @@ With the release of Whisk, Protocol 23, the [token interface] has seen some chan ## Run the Example -First go through the [Setup] process to get your development environment configured, then clone the `v23.0.0` tag of `soroban-examples` repository: +First go through the [Setup] process to get your development environment configured, then clone the `soroban-examples` repository: ```sh -git clone -b v23.0.0 https://github.com/stellar/soroban-examples +git clone https://github.com/stellar/soroban-examples ``` Or, skip the development environment setup and open this example in [GitHub Codespaces][open-in-github-codespaces] or [Code Anywhere][open-in-code-anywhere]. @@ -505,7 +505,7 @@ pub enum DataKey { -Ref: https://github.com/stellar/soroban-examples/tree/v23.0.0/token +Ref: https://github.com/stellar/soroban-examples/tree/main/token ## How it Works @@ -599,7 +599,7 @@ Of course, you will want your token to behave in an _intuitive_ and _transparent ## Tests -Open the [`token/src/test.rs`](https://github.com/stellar/soroban-examples/tree/v23.0.0/token/src/test.rs) file to follow along. +Open the [`token/src/test.rs`](https://github.com/stellar/soroban-examples/tree/main/token/src/test.rs) file to follow along. ```rust title="token/src/test.rs" #![cfg(test)] From 441134938779cb2b2fcb557f323868adde7f3998 Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 10 Sep 2026 20:25:09 +0000 Subject: [PATCH 4/5] resync token doc with main; fix test count --- docs/build/smart-contracts/example-contracts/tokens.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/build/smart-contracts/example-contracts/tokens.mdx b/docs/build/smart-contracts/example-contracts/tokens.mdx index 421a4136a..68ae7f506 100644 --- a/docs/build/smart-contracts/example-contracts/tokens.mdx +++ b/docs/build/smart-contracts/example-contracts/tokens.mdx @@ -319,7 +319,7 @@ impl Token { } } -#[contractimpl] +#[contractimpl(contracttrait)] impl TokenInterface for Token { fn allowance(e: Env, from: Address, spender: Address) -> i128 { e.storage() @@ -338,6 +338,8 @@ impl TokenInterface for Token { .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); write_allowance(&e, from.clone(), spender.clone(), amount, live_until_ledger); + // The event's `expiration_ledger` data field name is unchanged to + // preserve on-chain event compatibility (soroban-token-sdk::events::Approve). events::Approve { from, spender, @@ -877,7 +879,7 @@ fn test_zero_allowance() { } ``` -The token example implements eight different tests to cover a wide array of potential behaviors and problems. However, all of the tests start with a few common pieces. In any test, the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run in. +The token example implements six different tests to cover a wide array of potential behaviors and problems. However, all of the tests start with a few common pieces. In any test, the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run in. ```rust let e = Env::default(); From e2de84a0c9e9326b9c36f3e056f43e67183ea3b9 Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 11 Sep 2026 22:15:51 +1000 Subject: [PATCH 5/5] Update tokens.mdx --- docs/build/smart-contracts/example-contracts/tokens.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/build/smart-contracts/example-contracts/tokens.mdx b/docs/build/smart-contracts/example-contracts/tokens.mdx index 68ae7f506..4edcc2e86 100644 --- a/docs/build/smart-contracts/example-contracts/tokens.mdx +++ b/docs/build/smart-contracts/example-contracts/tokens.mdx @@ -338,8 +338,6 @@ impl TokenInterface for Token { .extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT); write_allowance(&e, from.clone(), spender.clone(), amount, live_until_ledger); - // The event's `expiration_ledger` data field name is unchanged to - // preserve on-chain event compatibility (soroban-token-sdk::events::Approve). events::Approve { from, spender,