Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
30c56ef
feat(rwa): add standalone country compliance modules
pasevin Mar 23, 2026
da529e5
refactor(rwa): move country module tests into sibling files
pasevin Mar 24, 2026
a6babd6
Merge branch 'main' into feat/rwa-country-standalone
pasevin Apr 10, 2026
27b08c3
chore: sync Cargo.lock with workspace manifests
pasevin Apr 10, 2026
301019a
refactor: apply storage-first pattern to country modules
pasevin Apr 10, 2026
ff8dadd
Merge remote-tracking branch 'upstream/main' into feat/rwa-country-st…
pasevin Apr 10, 2026
afa1dd8
chore: sync Cargo.lock after merging upstream/main v0.7.1
pasevin Apr 10, 2026
506a03f
refactor: finish country module alignment
pasevin Apr 10, 2026
2188957
refactor: align country modules with native traits
pasevin Apr 29, 2026
b91cd5b
refactor: tidy country membership storage
pasevin Apr 29, 2026
bd01f0b
chore: refresh ethnum lockfile entry
pasevin Apr 29, 2026
43764a1
Merge branch 'main' into feat/rwa-country-standalone
pasevin Apr 29, 2026
b44ecf8
refactor: add country allow event helpers
pasevin Apr 29, 2026
abca49c
refactor: wire country event helpers
pasevin Apr 30, 2026
f4b49bd
style: align country storage docs
pasevin Apr 30, 2026
5da6138
refactor: compose country module traits
pasevin Apr 30, 2026
8865101
style: order country module items
pasevin May 1, 2026
4d9ad42
refactor: use access control admin helpers
pasevin May 5, 2026
716a8a6
style: use full country module paths
pasevin May 5, 2026
5394955
docs: polish country trait docs
pasevin May 5, 2026
a06052b
docs: shorten country storage error links
pasevin May 5, 2026
55da13e
docs: fix country error link targets
pasevin May 5, 2026
3d061fd
chore: refresh country example lockfile
pasevin May 5, 2026
5b05459
Merge branch 'main' into feat/rwa-country-standalone
pasevin May 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ members = [
"examples/ownable",
"examples/pausable",
"examples/rwa/*",
"examples/rwa-country-allow",
"examples/rwa-country-restrict",
"examples/sac-admin-generic",
"examples/sac-admin-wrapper",
"examples/multisig-smart-account/*",
Expand Down
22 changes: 22 additions & 0 deletions examples/rwa-country-allow/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "rwa-country-allow"
edition.workspace = true
license.workspace = true
repository.workspace = true
publish = false
version.workspace = true
authors.workspace = true

[package.metadata.stellar]
cargo_inherit = true

[lib]
crate-type = ["cdylib", "rlib"]
doctest = false

[dependencies]
soroban-sdk = { workspace = true }
stellar-tokens = { workspace = true }

[dev-dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }
101 changes: 101 additions & 0 deletions examples/rwa-country-allow/src/contract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use soroban_sdk::{contract, contractimpl, contracttype, Address, Env, String, Vec};
use stellar_tokens::rwa::compliance::modules::{
country_allow::storage as country_allow,
storage::{
get_compliance_address, module_name, set_compliance_address, set_irs_address,
ComplianceModuleStorageKey,
},
ComplianceModule,
};

#[contracttype]
enum DataKey {
Admin,
}

#[contract]
pub struct CountryAllowContract;

fn set_admin(e: &Env, admin: &Address) {
e.storage().instance().set(&DataKey::Admin, admin);
}

fn get_admin(e: &Env) -> Address {
e.storage().instance().get(&DataKey::Admin).expect("admin must be set")
}
Comment thread
pasevin marked this conversation as resolved.
Outdated

fn require_module_admin_or_compliance_auth(e: &Env) {
if let Some(compliance) =
e.storage().instance().get::<_, Address>(&ComplianceModuleStorageKey::Compliance)
{
compliance.require_auth();
} else {
get_admin(e).require_auth();
}
}

#[contractimpl]
impl CountryAllowContract {
pub fn __constructor(e: &Env, admin: Address) {
set_admin(e, &admin);
}

pub fn set_identity_registry_storage(e: &Env, token: Address, irs: Address) {
require_module_admin_or_compliance_auth(e);
set_irs_address(e, &token, &irs);
}

pub fn add_allowed_country(e: &Env, token: Address, country: u32) {
require_module_admin_or_compliance_auth(e);
country_allow::add_allowed_country(e, &token, country);
}

pub fn remove_allowed_country(e: &Env, token: Address, country: u32) {
require_module_admin_or_compliance_auth(e);
country_allow::remove_allowed_country(e, &token, country);
}

pub fn batch_allow_countries(e: &Env, token: Address, countries: Vec<u32>) {
require_module_admin_or_compliance_auth(e);
country_allow::batch_allow_countries(e, &token, &countries);
}

pub fn batch_disallow_countries(e: &Env, token: Address, countries: Vec<u32>) {
require_module_admin_or_compliance_auth(e);
country_allow::batch_disallow_countries(e, &token, &countries);
}

pub fn is_country_allowed(e: &Env, token: Address, country: u32) -> bool {
country_allow::is_country_allowed(e, &token, country)
}
}

#[contractimpl(contracttrait)]
impl ComplianceModule for CountryAllowContract {
fn on_transfer(_e: &Env, _from: Address, _to: Address, _amount: i128, _token: Address) {}

fn on_created(_e: &Env, _to: Address, _amount: i128, _token: Address) {}

fn on_destroyed(_e: &Env, _from: Address, _amount: i128, _token: Address) {}

fn can_transfer(e: &Env, _from: Address, to: Address, _amount: i128, token: Address) -> bool {
country_allow::can_transfer(e, &to, &token)
}

fn can_create(e: &Env, to: Address, _amount: i128, token: Address) -> bool {
country_allow::can_transfer(e, &to, &token)
}
Comment thread
pasevin marked this conversation as resolved.
Outdated

fn name(e: &Env) -> String {
module_name(e, "CountryAllowModule")
}

fn get_compliance_address(e: &Env) -> Address {
get_compliance_address(e)
}

fn set_compliance_address(e: &Env, compliance: Address) {
get_admin(e).require_auth();
set_compliance_address(e, &compliance);
}
}
5 changes: 5 additions & 0 deletions examples/rwa-country-allow/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#![no_std]

pub mod contract;
#[cfg(test)]
mod test;
Loading
Loading