-
Notifications
You must be signed in to change notification settings - Fork 95
feat: Deployment Scripts and Configuration for NFT & Reputation Contracts #775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events
- Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration
- Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections
- Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens
- Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens
- Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API
… and change crate-type to just (cdylib)
…base and the tests did not compile
…ey are now used with the contractevent and topic macro
…e) for the different files that propagate the events
…ndfi-org/kindfi into feat/kindfi-nft-open-zeppelin
…on and security of contract initialization
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the
WalkthroughThis PR introduces complete implementations of two Soroban smart contracts for KindFi: an NFT contract with metadata management and access control, and a Reputation contract with a five-tier level system. Includes comprehensive deployment scripts, configuration templates, documentation, and test suites for both contracts. Changes
Sequence Diagram(s)sequenceDiagram
actor User as User/Caller
participant ReputationC as Reputation Contract
participant StorageM as Persistent Storage
participant NFTContract as NFT Contract
participant RolesMgmt as Access Control/Roles
User->>ReputationC: record_event(user, event_type)
activate ReputationC
ReputationC->>RolesMgmt: verify_recorder_role(caller)
activate RolesMgmt
RolesMgmt-->>ReputationC: authorized
deactivate RolesMgmt
ReputationC->>StorageM: get_points(user)
activate StorageM
StorageM-->>ReputationC: current_points
deactivate StorageM
ReputationC->>ReputationC: calculate_new_level(current_points + event_points)
alt Level Changed
ReputationC->>StorageM: set_user_level(user, new_level)
ReputationC->>StorageM: get_user_nft_token_id(user)
activate StorageM
StorageM-->>ReputationC: token_id
deactivate StorageM
ReputationC->>NFTContract: get_metadata(token_id)
activate NFTContract
NFTContract-->>ReputationC: nft_metadata
deactivate NFTContract
ReputationC->>ReputationC: update_attributes_with_level(nft_metadata, new_level)
ReputationC->>NFTContract: update_metadata(token_id, updated_metadata)
activate NFTContract
NFTContract-->>ReputationC: success
deactivate NFTContract
ReputationC->>ReputationC: emit NFTUpgradedEventData
end
ReputationC->>StorageM: set_points(user, new_total_points)
ReputationC->>StorageM: add_user_event(user, event_record)
ReputationC-->>User: new_total_points
deactivate ReputationC
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
👀 Review HighlightsConsider the comprehensive scope here — this PR delivers two full contracts with interconnected logic. We could enhance clarity by:
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 21
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/contract/README.md (1)
158-160: Update the README SDK version reference to match current dependenciesThe setup section documents Soroban SDK v22.0.6, but the project currently uses 23.4.0. Consider updating line 159 to reflect the actual dependency version. For reference, soroban-sdk 23.4.0 requires Rust 1.84.0 as the minimum supported version. Keeping version references current in documentation helps developers understand compatibility requirements and aligns with documentation maintenance best practices.
🤖 Fix all issues with AI agents
In `@apps/contract/.env.example`:
- Around line 8-103: Dotenv-linter flags come from quoted values and key
ordering in the .env.example (notably NETWORK_PASSPHRASE, NETWORK, RPC_URL,
HORIZON_URL and other variables), so update the dotenv-linter configuration to
allow quoted values for entries containing spaces (e.g., NETWORK_PASSPHRASE)
and/or disable the strict key-order rule used by CI; specifically add or modify
the linter config (the repo's dotenv-linter settings or workflow step) to permit
quoted strings and to ignore ordering for .env.example, or alternatively
normalize non-space values by removing unnecessary quotes while keeping quotes
for passphrases like NETWORK_PASSPHRASE.
In `@apps/contract/contracts/nft-kindfi/src/lib.rs`:
- Around line 129-147: The update_metadata function emits a duplicate event:
metadata::set_metadata already publishes MetadataSetEventData and
update_metadata then publishes MetadataUpdatedEventData; pick one pattern and
remove duplication by either (A) stop publishing MetadataUpdatedEventData in
update_metadata and rely on metadata::set_metadata's MetadataSetEventData, or
(B) add a parameter to metadata::set_metadata (e.g., emit_event: bool) to
control emission and call it with emit_event=false from update_metadata, then
publish MetadataUpdatedEventData only once; update references to
MetadataSetEventData, MetadataUpdatedEventData, metadata::set_metadata, and
update_metadata accordingly to keep a single event emission.
- Around line 79-84: The constructor currently only checks storage_get_admin(e)
allowing re-initialization after renounce_admin() clears the admin; add a
persistent initialized flag (e.g., storage_get_is_initialized /
storage_set_is_initialized or reuse an is_initialized key like in Reputation)
and change __constructor to first require that is_initialized is false, then set
is_initialized = true after successful init; ensure
storage_renounce_admin/renounce_admin do not clear that flag so the
initialization guard remains permanent and cannot be bypassed by removing the
admin.
In `@apps/contract/contracts/nft-kindfi/src/metadata.rs`:
- Around line 11-16: Replace panics in require_valid_metadata with contract
errors: add an Env parameter to require_valid_metadata(&Env, metadata:
&NFTMetadata) and use panic_with_error! (or return a Result and call
panic_with_error! on Err) to emit Error::InvalidMetadataName when name is empty
and Error::InvalidMetadataImageUri when image_uri is empty; also add those two
variants to the errors module so the contract produces informative on-chain
errors instead of generic assert panics.
In `@apps/contract/contracts/nft-kindfi/src/types.rs`:
- Around line 20-28: Add Debug, Eq, and PartialEq to the StorageKey derives so
it matches NFTMetadata and improves debugging/testing; update the enum
declaration that currently has #[derive(Clone)] (and #[contracttype]) to include
Debug, PartialEq, and Eq alongside Clone so StorageKey implements those traits.
In `@apps/contract/contracts/reputation/README.md`:
- Around line 439-472: Add validation in the contract's initialization path to
ensure provided addresses are non-zero/valid: in the initialize function verify
the admin address and the nft_contract_id (or nft_contract Address) are not the
zero/empty address and return/abort with a clear error if invalid; also validate
inputs in set_nft_contract and register_user_nft to guard against invalid
addresses or token IDs before performing state changes or cross-contract calls
(see initialize, set_nft_contract, register_user_nft, and nft_client.rs /
try_upgrade_nft for where to add these checks).
In `@apps/contract/contracts/reputation/src/lib.rs`:
- Around line 393-401: The code currently uses
Level::from_u32(level).unwrap_or(Level::Rookie) which silently maps invalid
values to Rookie; change set_permission_threshold to explicitly reject invalid
levels by checking Level::from_u32(level) and calling
panic_with_error!(InvalidLevelThreshold) when it returns None, then proceed with
set_permission_threshold(e, threshold_type, valid_level) and
Self::extend_instance_ttl(e); apply the same change to get_level_threshold to
ensure invalid input raises InvalidLevelThreshold rather than defaulting.
- Around line 81-95: The constructor __constructor should validate that admin is
not the zero/invalid address and that nft_contract (when Some) is not zero
before persisting; add checks after admin.require_auth() and before set_admin(e,
&admin) to compare admin against the zero address (e.g.
Address::zero()/equivalent) and panic_with_error!(e, Error::InvalidAdmin) if it
is invalid, and if let Some(nft_addr) = nft_contract { validate nft_addr
similarly and panic_with_error!(e, Error::InvalidAddress) before calling
set_nft_contract(e, &nft_addr); keep existing is_initialized() guard and set_*
calls but perform the new validations first.
In `@apps/contract/contracts/reputation/src/nft_client.rs`:
- Around line 99-139: Introduce a small type alias to simplify the nested Result
types returned by e.try_invoke_contract and use it in try_get_nft_metadata and
try_update_nft_metadata: define a generic alias (e.g., InvokeCallResult<T> =
Result<Result<T, ConversionError>, Result<InvokeError, InvokeError>>) and change
the local variable types in try_get_nft_metadata and try_update_nft_metadata to
use InvokeCallResult<Option<NFTMetadata>> and InvokeCallResult<(), respectively,
then keep the existing match and matches! logic unchanged to preserve behavior
while improving readability; reference e.try_invoke_contract,
try_get_nft_metadata, try_update_nft_metadata, NFTMetadata, ConversionError, and
InvokeError when making the change.
In `@apps/contract/contracts/reputation/src/storage.rs`:
- Around line 70-95: The user event Vec stored under StorageKey::UserEvents
(accessed by get_user_events and mutated in add_user_event) can grow unbounded;
add a fixed MAX_USER_EVENTS constant and enforce a rolling window when
appending: after loading events in add_user_event, if events.len() >=
MAX_USER_EVENTS remove the oldest entry(s) (or truncate to keep the most recent
MAX_USER_EVENTS-1) before pushing the new ReputationEventRecord, then persist
and extend TTL as before; also consider trimming in get_user_events if needed so
stored data never exceeds the cap.
- Around line 20-39: get_points currently calls
persistent().get(&key).unwrap_or(0) so you can't tell if a zero value exists and
TTL is only extended when points > 0; change get_points to read the Option<u32>
(e.g., let opt = e.storage().persistent().get::<_, u32>(&key)) and if
opt.is_some() extend TTL with PERSISTENT_TTL_THRESHOLD and PERSISTENT_TTL_AMOUNT
and return opt.unwrap_or(0), otherwise return 0; keep set_points as-is (it
already extends TTL) and reference StorageKey::UserPoints, get_points,
set_points, PERSISTENT_TTL_THRESHOLD, PERSISTENT_TTL_AMOUNT in your change.
In `@apps/contract/contracts/reputation/src/test.rs`:
- Around line 420-478: Add an integration test (e.g.,
test_update_nft_on_level_up) that registers a mock NFT contract via
TestEnv/test.client.set_nft_contract, deploys or injects a lightweight mock that
records mint/transfer calls, registers an initial NFT for a user with
test.client.register_user_nft, then simulate the user leveling up (by invoking
the same path your system uses — e.g., test.client.record_event with
EventType::QuestCompletion or the specific level-up helper if present) and
finally assert that (1) test.client.get_user_nft_token_id(&user) reflects the
updated token id and (2) the mock NFT contract recorded the expected
mint/transfer call for that user; ensure the test grants recorder/admin roles as
needed (use TestEnv, Address::generate, grant_recorder_role, set_nft_contract,
register_user_nft, get_user_nft_token_id, and record_event) and fails if the
mock did not observe the expected NFT update.
In `@apps/contract/contracts/reputation/src/types.rs`:
- Around line 41-81: Add an idiomatic TryFrom<u32> implementation for Level to
replace/augment from_u32: implement impl TryFrom<u32> for Level { type Error =
(); fn try_from(value: u32) -> Result<Self, Self::Error> {
Level::from_u32(value).ok_or(()) } } so callers can use ? and standard
conversion patterns (keep existing as_u32 and from_u32 for compatibility or
remove if desired); ensure std::convert::TryFrom is in scope or imported if
needed and consider replacing call sites that can benefit from the Result-based
conversion.
- Around line 95-119: Add a Debug derive to the StorageKey enum so storage keys
are printable for debugging: update the StorageKey declaration (the enum named
StorageKey) to include #[derive(Debug)] alongside existing derives (currently
#[derive(Clone)]), ensuring the #[contracttype] attribute remains intact and
compile passes.
In `@apps/contract/rust-toolchain.toml`:
- Around line 1-4: The toolchain currently uses a floating channel ("channel" =
"stable"); change the channel in the [toolchain] table to a specific Rust
version (e.g., "1.84.0" or a newer explicit stable version) so builds are
reproducible and the tier-2 target "wasm32v1-none" remains supported; keep the
existing "targets" and "components" entries (targets = ["wasm32v1-none"],
components = ["rustfmt","clippy","rust-src"]) but replace the channel value with
the pinned version string.
In `@apps/contract/scripts/deploy-nft.sh`:
- Around line 188-201: Add optional CLI flags (--grant-minter <ADDR>,
--grant-burner <ADDR>, --reputation-contract <ADDR>) to the deploy script and,
after successful deployment (when NFT_CONTRACT_ID and ADMIN_ADDRESS are set),
automatically execute the corresponding grant_role stellar invocations instead
of only printing templates: if --grant-minter provided call stellar contract
invoke ... --id $NFT_CONTRACT_ID -- grant_role --account <ADDR> --role 'minter'
--caller $ADMIN_ADDRESS; similarly for --grant-burner; if --reputation-contract
provided first obtain the metadata_manager role value by invoking stellar
contract invoke ... --id $NFT_CONTRACT_ID -- metadata_manager_role and then call
grant_role with --account $REPUTATION_CONTRACT and that role; ensure each
invocation checks for errors and only runs when the respective flag/variable is
non-empty.
- Around line 182-186: The current verification logic using VERIFIED_ADMIN and
ADMIN_ADDRESS allows false positives because it treats any value other than
"VERIFICATION_FAILED" as success; update the if/else to require an explicit
match (e.g., VERIFIED_ADMIN contains or equals ADMIN_ADDRESS) for the success
branch, add a distinct branch to handle the "VERIFICATION_FAILED" case (log a
verification error), and add a mismatch branch (log a warning that verification
succeeded but admin does not match) so the three outcomes—match, mismatch, and
verification failure—are handled explicitly; locate and modify the conditional
that references VERIFIED_ADMIN and ADMIN_ADDRESS in the deploy verification
block to implement this stricter logic.
- Around line 130-133: The confirmation prompt uses read without the -r flag so
backslashes in user input can be interpreted; update the read invocation that
assigns to confirm (the line starting with read -p "Are you sure you want to
continue? (yes/no): " confirm) to use read -r -p so input is read raw and
backslashes are not treated as escape sequences, keeping the subsequent check if
[[ "$confirm" != "yes" ]] then unchanged.
In `@apps/contract/scripts/deploy-reputation.sh`:
- Around line 256-262: Add optional CLI flags --grant-recorder <ADDRESS> and
--grant-config <ADDRESS> to the deploy-reputation.sh argument parsing, and if
provided invoke the same grant_role commands shown in the template using the
existing variables (NETWORK, SOURCE, REPUTATION_CONTRACT_ID, ADMIN_ADDRESS) to
run: stellar contract invoke ... --grant_role --account <ADDRESS> --role
'recorder' (or 'config') --caller $ADMIN_ADDRESS; ensure flags are parsed where
other options like --nft-contract are handled and that the commands only run
when the corresponding variable (e.g., GRANT_RECORDER, GRANT_CONFIG) is
non-empty, with error handling/logging on failure.
- Around line 185-189: The current OR logic with VERIFIED_ADMIN and
ADMIN_ADDRESS causes false positives; change the conditional to explicitly check
for three cases: first if VERIFIED_ADMIN equals "VERIFICATION_FAILED" then treat
as verification failure and echo an error, second if VERIFIED_ADMIN contains the
expected ADMIN_ADDRESS (use the existing pattern match with *"$ADMIN_ADDRESS"*)
then echo "Contract admin verified!", and otherwise echo a clear mismatch
warning showing both VERIFIED_ADMIN and ADMIN_ADDRESS; update the block that
references VERIFIED_ADMIN and ADMIN_ADDRESS accordingly to implement these three
branches.
- Around line 124-127: The prompt reading uses read -p "..." confirm which can
interpret backslashes; change it to read -r -p "Are you sure you want to
continue? (yes/no): " confirm so input is read raw and backslashes are preserved
(adjust the read invocation where the prompt and confirm variable are used).
| # Network to deploy to: testnet, futurenet, or mainnet | ||
| NETWORK="testnet" | ||
|
|
||
| # Network passphrase | ||
| # Testnet: "Test SDF Network ; September 2015" | ||
| # Futurenet: "Test SDF Future Network ; October 2022" | ||
| # Mainnet: "Public Global Stellar Network ; September 2015" | ||
| NETWORK_PASSPHRASE="Test SDF Network ; September 2015" | ||
|
|
||
| # RPC URL | ||
| # Testnet: https://soroban-testnet.stellar.org | ||
| # Futurenet: https://rpc-futurenet.stellar.org | ||
| # Mainnet: https://soroban.stellar.org (or your preferred RPC provider) | ||
| RPC_URL="https://soroban-testnet.stellar.org" | ||
|
|
||
| # Horizon URL | ||
| # Testnet: https://horizon-testnet.stellar.org | ||
| # Futurenet: https://horizon-futurenet.stellar.org | ||
| # Mainnet: https://horizon.stellar.org | ||
| HORIZON_URL="https://horizon-testnet.stellar.org" | ||
|
|
||
| # ============================================================================= | ||
| # Account Configuration | ||
| # ============================================================================= | ||
|
|
||
| # Stellar account identity name (from stellar keys) | ||
| SOURCE_ACCOUNT="bran" | ||
|
|
||
| # Funding account secret key (NEVER commit this!) | ||
| # STELLAR_FUNDING_SECRET_KEY="" | ||
|
|
||
| # ============================================================================= | ||
| # Auth Contracts | ||
| # ============================================================================= | ||
|
|
||
| # Auth Controller Contract | ||
| AUTH_CONTROLLER_CONTRACT_ID="" | ||
| AUTH_CONTROLLER_WASM_HASH="" | ||
|
|
||
| # Account Contract | ||
| ACCOUNT_CONTRACT_ID="" | ||
| ACCOUNT_WASM_HASH="" | ||
|
|
||
| # Account Factory Contract | ||
| ACCOUNT_FACTORY_CONTRACT_ID="" | ||
| ACCOUNT_FACTORY_WASM_HASH="" | ||
|
|
||
| # ============================================================================= | ||
| # NFT Contract | ||
| # ============================================================================= | ||
|
|
||
| # KindFi NFT Contract | ||
| NFT_CONTRACT_ID="" | ||
| NFT_WASM_HASH="" | ||
| NFT_ADMIN_ADDRESS="" | ||
|
|
||
| # NFT Collection Configuration | ||
| NFT_NAME="KindFi Kinder NFT" | ||
| NFT_SYMBOL="KINDER" | ||
| NFT_BASE_URI="https://api.kindfi.org/nft/" | ||
|
|
||
| # ============================================================================= | ||
| # Reputation Contract | ||
| # ============================================================================= | ||
|
|
||
| # Reputation Contract | ||
| REPUTATION_CONTRACT_ID="" | ||
| REPUTATION_WASM_HASH="" | ||
| REPUTATION_ADMIN_ADDRESS="" | ||
|
|
||
| # Reputation Contract Configuration | ||
| # Set to NFT_CONTRACT_ID for automatic NFT metadata updates on level up | ||
| REPUTATION_NFT_CONTRACT="" | ||
|
|
||
| # ============================================================================= | ||
| # Role Addresses (Optional - for automated role assignment) | ||
| # ============================================================================= | ||
|
|
||
| # NFT Contract Roles | ||
| NFT_MINTER_ADDRESS="" | ||
| NFT_BURNER_ADDRESS="" | ||
| # Note: REPUTATION_CONTRACT_ID should be granted metadata_manager role | ||
|
|
||
| # Reputation Contract Roles | ||
| REPUTATION_RECORDER_ADDRESS="" | ||
| REPUTATION_CONFIG_ADDRESS="" | ||
|
|
||
| # ============================================================================= | ||
| # Development / Testing | ||
| # ============================================================================= | ||
|
|
||
| # Enable verbose logging | ||
| VERBOSE="false" | ||
|
|
||
| # Skip confirmation prompts (use with caution!) | ||
| SKIP_CONFIRMATION="false" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, comprehensive env template; consider addressing dotenv-linter warnings.
Since dotenv-linter flags quoted values and key ordering here, we could enhance this by either configuring the linter to allow quoted strings (recommended for passphrases with spaces) or suppressing these warnings so CI doesn’t stay noisy.
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 9-9: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 21-21: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 27-27: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 34-34: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 44-44: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 45-45: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 48-48: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 49-49: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 52-52: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 53-53: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 60-60: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 61-61: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 62-62: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 62-62: [UnorderedKey] The NFT_ADMIN_ADDRESS key should go before the NFT_CONTRACT_ID key
(UnorderedKey)
[warning] 66-66: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 67-67: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 67-67: [UnorderedKey] The NFT_BASE_URI key should go before the NFT_NAME key
(UnorderedKey)
[warning] 74-74: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 75-75: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 76-76: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 76-76: [UnorderedKey] The REPUTATION_ADMIN_ADDRESS key should go before the REPUTATION_CONTRACT_ID key
(UnorderedKey)
[warning] 80-80: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 87-87: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 88-88: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 88-88: [UnorderedKey] The NFT_BURNER_ADDRESS key should go before the NFT_MINTER_ADDRESS key
(UnorderedKey)
[warning] 92-92: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 93-93: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 93-93: [UnorderedKey] The REPUTATION_CONFIG_ADDRESS key should go before the REPUTATION_RECORDER_ADDRESS key
(UnorderedKey)
[warning] 100-100: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 103-103: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
🤖 Prompt for AI Agents
In `@apps/contract/.env.example` around lines 8 - 103, Dotenv-linter flags come
from quoted values and key ordering in the .env.example (notably
NETWORK_PASSPHRASE, NETWORK, RPC_URL, HORIZON_URL and other variables), so
update the dotenv-linter configuration to allow quoted values for entries
containing spaces (e.g., NETWORK_PASSPHRASE) and/or disable the strict key-order
rule used by CI; specifically add or modify the linter config (the repo's
dotenv-linter settings or workflow step) to permit quoted strings and to ignore
ordering for .env.example, or alternatively normalize non-space values by
removing unnecessary quotes while keeping quotes for passphrases like
NETWORK_PASSPHRASE.
| pub fn __constructor(e: &Env, admin: Address, name: String, symbol: String, base_uri: String) { | ||
| // Check if already initialized by checking if admin is set | ||
| admin.require_auth(); | ||
| if storage_get_admin(e).is_some() { | ||
| panic_with_error!(e, Error::AlreadyInitialized); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's examine the NFT contract implementation
fd -t f "lib.rs" apps/contract/contracts/nft-kindfi/src/ | head -5Repository: kindfi-org/kindfi
Length of output: 106
🏁 Script executed:
# Read the NFT contract to understand the full initialization logic
cat -n apps/contract/contracts/nft-kindfi/src/lib.rs | head -150Repository: kindfi-org/kindfi
Length of output: 6592
🏁 Script executed:
# Check if there's a renounce_admin function in the NFT contract
rg "renounce_admin" apps/contract/contracts/nft-kindfi/Repository: kindfi-org/kindfi
Length of output: 432
🏁 Script executed:
# Check the Reputation contract initialization pattern
rg -A 10 "initialized" apps/contract/contracts/reputation/src/lib.rsRepository: kindfi-org/kindfi
Length of output: 1267
🏁 Script executed:
# Search for storage_get_admin in both contracts to understand the pattern
rg -B 5 -A 5 "storage_get_admin" apps/contract/contracts/Repository: kindfi-org/kindfi
Length of output: 6014
🏁 Script executed:
# Find the full renounce_admin implementation in NFT contract
rg -B 3 -A 10 "fn renounce_admin" apps/contract/contracts/nft-kindfi/src/lib.rsRepository: kindfi-org/kindfi
Length of output: 253
🏁 Script executed:
# Check if NFT contract has any is_initialized or similar pattern
rg "is_initialized\|set_initialized" apps/contract/contracts/nft-kindfi/src/Repository: kindfi-org/kindfi
Length of output: 43
🏁 Script executed:
# Look at the storage module to understand what renounce_admin does
fd -t f "storage.rs" apps/contract/contracts/nft-kindfi/src/ 2>/dev/nullRepository: kindfi-org/kindfi
Length of output: 43
🏁 Script executed:
# Check stellar_access module if available in repo to understand renounce_admin behavior
rg -B 2 -A 10 "pub fn renounce_admin" --type rustRepository: kindfi-org/kindfi
Length of output: 43
🏁 Script executed:
# Check the Reputation contract's storage module for is_initialized implementation
cat -n apps/contract/contracts/reputation/src/storage.rs | grep -A 10 "is_initialized\|set_initialized"Repository: kindfi-org/kindfi
Length of output: 403
🏁 Script executed:
# Look for tests that might show renounce_admin behavior
rg -B 5 -A 15 "renounce_admin" apps/contract/contracts/nft-kindfi/src/test.rsRepository: kindfi-org/kindfi
Length of output: 43
🏁 Script executed:
# Check Reputation contract tests to see how initialized flag prevents re-init
rg -B 5 -A 15 "renounce_admin\|AlreadyInitialized" apps/contract/contracts/reputation/src/test.rsRepository: kindfi-org/kindfi
Length of output: 43
Prevent re-initialization after admin renounce
The initialization guard checks only storage_get_admin(e).is_some(). Since renounce_admin() clears the admin through storage_renounce_admin(e), the guard can be bypassed after renouncing—allowing the constructor to be called again with a different admin. We could enhance this by adding a persistent initialized flag (similar to the Reputation contract's is_initialized pattern) to make the guard permanent and independent of admin state.
🤖 Prompt for AI Agents
In `@apps/contract/contracts/nft-kindfi/src/lib.rs` around lines 79 - 84, The
constructor currently only checks storage_get_admin(e) allowing
re-initialization after renounce_admin() clears the admin; add a persistent
initialized flag (e.g., storage_get_is_initialized / storage_set_is_initialized
or reuse an is_initialized key like in Reputation) and change __constructor to
first require that is_initialized is false, then set is_initialized = true after
successful init; ensure storage_renounce_admin/renounce_admin do not clear that
flag so the initialization guard remains permanent and cannot be bypassed by
removing the admin.
| pub fn update_metadata(e: &Env, caller: Address, token_id: u32, nft_metadata: NFTMetadata) { | ||
| // Verify caller has metadata_manager role (using full name with Symbol::new) | ||
| let role = Symbol::new(e, METADATA_MANAGER_ROLE); | ||
| if storage_has_role(e, &caller, &role).is_none() { | ||
| panic_with_error!(e, Error::Unauthorized); | ||
| } | ||
| caller.require_auth(); | ||
|
|
||
| // Verify token exists by checking owner (will panic if not found) | ||
| let _ = Base::owner_of(e, token_id); | ||
|
|
||
| // Update metadata | ||
| metadata::set_metadata(e, token_id, &nft_metadata); | ||
|
|
||
| // Emit metadata updated event | ||
| MetadataUpdatedEventData { | ||
| token_id, | ||
| metadata: nft_metadata, | ||
| }.publish(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's locate and read the lib.rs file at the specified lines
find . -path "*/contracts/nft-kindfi/src/lib.rs" -type fRepository: kindfi-org/kindfi
Length of output: 108
🏁 Script executed:
# Also find the metadata.rs file
find . -path "*/contracts/nft-kindfi/src/metadata.rs" -type fRepository: kindfi-org/kindfi
Length of output: 113
🏁 Script executed:
cat -n ./apps/contract/contracts/nft-kindfi/src/lib.rs | sed -n '120,160p'Repository: kindfi-org/kindfi
Length of output: 1836
🏁 Script executed:
cat -n ./apps/contract/contracts/nft-kindfi/src/metadata.rs | sed -n '1,50p'Repository: kindfi-org/kindfi
Length of output: 2151
🏁 Script executed:
rg "set_metadata" ./apps/contract/contracts/nft-kindfi/src/ -A 2 -B 2Repository: kindfi-org/kindfi
Length of output: 1732
🏁 Script executed:
# Look for event definitions
rg "MetadataSetEventData|MetadataUpdatedEventData" ./apps/contract/contracts/nft-kindfi/src/ -B 2 -A 4Repository: kindfi-org/kindfi
Length of output: 3280
🏁 Script executed:
# Check mint.rs to see how it handles metadata events
rg -A 10 "metadata::set_metadata" ./apps/contract/contracts/nft-kindfi/src/mint.rsRepository: kindfi-org/kindfi
Length of output: 293
Consider refactoring to avoid redundant metadata event emissions
The update_metadata function currently triggers two events for a single operation: metadata::set_metadata() emits MetadataSetEventData (metadata.rs, lines 27-30), and then update_metadata also emits MetadataUpdatedEventData (lib.rs, lines 144-147). Since both events carry identical data structures, this creates duplicate signals. We could enhance this by either introducing a metadata update helper that suppresses the MetadataSetEventData emission, or relying solely on the MetadataSetEventData to maintain a consistent event pattern with the mint flow.
🤖 Prompt for AI Agents
In `@apps/contract/contracts/nft-kindfi/src/lib.rs` around lines 129 - 147, The
update_metadata function emits a duplicate event: metadata::set_metadata already
publishes MetadataSetEventData and update_metadata then publishes
MetadataUpdatedEventData; pick one pattern and remove duplication by either (A)
stop publishing MetadataUpdatedEventData in update_metadata and rely on
metadata::set_metadata's MetadataSetEventData, or (B) add a parameter to
metadata::set_metadata (e.g., emit_event: bool) to control emission and call it
with emit_event=false from update_metadata, then publish
MetadataUpdatedEventData only once; update references to MetadataSetEventData,
MetadataUpdatedEventData, metadata::set_metadata, and update_metadata
accordingly to keep a single event emission.
| /// Validates that the metadata fields meet minimum requirements. | ||
| /// Panics if validation fails. | ||
| fn require_valid_metadata(metadata: &NFTMetadata) { | ||
| assert!(metadata.name.len() > 0, "name cannot be empty"); | ||
| assert!(metadata.image_uri.len() > 0, "image_uri cannot be empty"); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider using contract errors for validation failures.
The validation logic is correct, but using assert! produces generic panic messages. We could enhance error handling by using panic_with_error! with custom error variants (e.g., Error::InvalidMetadataName, Error::InvalidMetadataImageUri) for more informative on-chain error reporting.
♻️ Suggested improvement
+use crate::errors::Error;
+use soroban_sdk::panic_with_error;
+
fn require_valid_metadata(metadata: &NFTMetadata) {
- assert!(metadata.name.len() > 0, "name cannot be empty");
- assert!(metadata.image_uri.len() > 0, "image_uri cannot be empty");
+ if metadata.name.len() == 0 {
+ panic_with_error!(e, Error::InvalidMetadataName);
+ }
+ if metadata.image_uri.len() == 0 {
+ panic_with_error!(e, Error::InvalidMetadataImageUri);
+ }
}Note: This would require adding an Env parameter and corresponding error variants to the errors module.
🤖 Prompt for AI Agents
In `@apps/contract/contracts/nft-kindfi/src/metadata.rs` around lines 11 - 16,
Replace panics in require_valid_metadata with contract errors: add an Env
parameter to require_valid_metadata(&Env, metadata: &NFTMetadata) and use
panic_with_error! (or return a Result and call panic_with_error! on Err) to emit
Error::InvalidMetadataName when name is empty and Error::InvalidMetadataImageUri
when image_uri is empty; also add those two variants to the errors module so the
contract produces informative on-chain errors instead of generic assert panics.
| /// Storage keys for the KindFi NFT contract. | ||
| #[contracttype] | ||
| #[derive(Clone)] | ||
| pub enum StorageKey { | ||
| /// Counter for sequential token IDs | ||
| TokenCounter, | ||
| /// Custom metadata storage per token ID | ||
| TokenMetadata(u32), | ||
| } No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Consider adding additional trait derives to StorageKey for consistency.
The StorageKey enum works well for type-safe storage access. We could enhance debugging and testing by adding Debug, Eq, and PartialEq derives to match the pattern used in NFTMetadata.
♻️ Suggested enhancement
/// Storage keys for the KindFi NFT contract.
#[contracttype]
-#[derive(Clone)]
+#[derive(Clone, Debug, Eq, PartialEq)]
pub enum StorageKey {
/// Counter for sequential token IDs
TokenCounter,
/// Custom metadata storage per token ID
TokenMetadata(u32),
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /// Storage keys for the KindFi NFT contract. | |
| #[contracttype] | |
| #[derive(Clone)] | |
| pub enum StorageKey { | |
| /// Counter for sequential token IDs | |
| TokenCounter, | |
| /// Custom metadata storage per token ID | |
| TokenMetadata(u32), | |
| } | |
| /// Storage keys for the KindFi NFT contract. | |
| #[contracttype] | |
| #[derive(Clone, Debug, Eq, PartialEq)] | |
| pub enum StorageKey { | |
| /// Counter for sequential token IDs | |
| TokenCounter, | |
| /// Custom metadata storage per token ID | |
| TokenMetadata(u32), | |
| } |
🤖 Prompt for AI Agents
In `@apps/contract/contracts/nft-kindfi/src/types.rs` around lines 20 - 28, Add
Debug, Eq, and PartialEq to the StorageKey derives so it matches NFTMetadata and
improves debugging/testing; update the enum declaration that currently has
#[derive(Clone)] (and #[contracttype]) to include Debug, PartialEq, and Eq
alongside Clone so StorageKey implements those traits.
| if [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]] || [[ "$VERIFIED_ADMIN" != "VERIFICATION_FAILED" ]]; then | ||
| echo "Contract admin verified!" | ||
| else | ||
| echo "Warning: Could not verify admin. Contract may still be deployed correctly." | ||
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
fd "deploy-nft.sh" --type fRepository: kindfi-org/kindfi
Length of output: 96
🏁 Script executed:
wc -l apps/contract/scripts/deploy-nft.shRepository: kindfi-org/kindfi
Length of output: 100
🏁 Script executed:
sed -n '170,200p' apps/contract/scripts/deploy-nft.shRepository: kindfi-org/kindfi
Length of output: 1296
Harden admin verification to avoid false positives
Good to see a post-deploy verification step. The current condition treats any non-VERIFICATION_FAILED output as success, which creates false positives even when the admin mismatches. Consider restructuring to make success contingent on an explicit admin match and handling the failure and mismatch cases separately.
💡 Proposed fix
-if [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]] || [[ "$VERIFIED_ADMIN" != "VERIFICATION_FAILED" ]]; then
- echo "Contract admin verified!"
-else
- echo "Warning: Could not verify admin. Contract may still be deployed correctly."
-fi
+if [[ "$VERIFIED_ADMIN" == "VERIFICATION_FAILED" ]]; then
+ echo "Warning: Could not verify admin. Contract may still be deployed correctly."
+elif [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]]; then
+ echo "Contract admin verified!"
+else
+ echo "Warning: Admin mismatch (expected $ADMIN_ADDRESS, got $VERIFIED_ADMIN)."
+fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]] || [[ "$VERIFIED_ADMIN" != "VERIFICATION_FAILED" ]]; then | |
| echo "Contract admin verified!" | |
| else | |
| echo "Warning: Could not verify admin. Contract may still be deployed correctly." | |
| fi | |
| if [[ "$VERIFIED_ADMIN" == "VERIFICATION_FAILED" ]]; then | |
| echo "Warning: Could not verify admin. Contract may still be deployed correctly." | |
| elif [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]]; then | |
| echo "Contract admin verified!" | |
| else | |
| echo "Warning: Admin mismatch (expected $ADMIN_ADDRESS, got $VERIFIED_ADMIN)." | |
| fi |
🤖 Prompt for AI Agents
In `@apps/contract/scripts/deploy-nft.sh` around lines 182 - 186, The current
verification logic using VERIFIED_ADMIN and ADMIN_ADDRESS allows false positives
because it treats any value other than "VERIFICATION_FAILED" as success; update
the if/else to require an explicit match (e.g., VERIFIED_ADMIN contains or
equals ADMIN_ADDRESS) for the success branch, add a distinct branch to handle
the "VERIFICATION_FAILED" case (log a verification error), and add a mismatch
branch (log a warning that verification succeeded but admin does not match) so
the three outcomes—match, mismatch, and verification failure—are handled
explicitly; locate and modify the conditional that references VERIFIED_ADMIN and
ADMIN_ADDRESS in the deploy verification block to implement this stricter logic.
| # Step 5: Grant initial roles (optional - admin can do this later) | ||
| echo "" | ||
| echo "=== Step 5: Role Assignment ===" | ||
| echo "Admin has been set during initialization." | ||
| echo "To grant additional roles, use:" | ||
| echo "" | ||
| echo " # Grant minter role" | ||
| echo " stellar contract invoke --network $NETWORK --source $SOURCE --id $NFT_CONTRACT_ID -- grant_role --account <ADDRESS> --role 'minter' --caller $ADMIN_ADDRESS" | ||
| echo "" | ||
| echo " # Grant burner role" | ||
| echo " stellar contract invoke --network $NETWORK --source $SOURCE --id $NFT_CONTRACT_ID -- grant_role --account <ADDRESS> --role 'burner' --caller $ADMIN_ADDRESS" | ||
| echo "" | ||
| echo " # Grant metadata_manager role (for Reputation contract integration)" | ||
| echo " stellar contract invoke --network $NETWORK --source $SOURCE --id $NFT_CONTRACT_ID -- grant_role --account <REPUTATION_CONTRACT_ID> --role \$(stellar contract invoke --network $NETWORK --source $SOURCE --id $NFT_CONTRACT_ID -- metadata_manager_role) --caller $ADMIN_ADDRESS" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Check if the file exists and get its total line count
if [ -f "apps/contract/scripts/deploy-nft.sh" ]; then
echo "File exists"
wc -l "apps/contract/scripts/deploy-nft.sh"
else
echo "File not found"
fiRepository: kindfi-org/kindfi
Length of output: 112
🏁 Script executed:
# Read the entire deploy-nft.sh script to understand context
cat -n "apps/contract/scripts/deploy-nft.sh"Repository: kindfi-org/kindfi
Length of output: 10270
Consider automating initial role grants
The script currently prints grant_role command templates in Step 5, but these must be executed manually post-deployment. Since the "Next steps" section (lines 263–266) explicitly mentions granting minter and metadata_manager roles as part of the deployment flow, we could enhance this by adding optional flags (e.g., --grant-minter <ADDRESS>, --grant-burner <ADDRESS>) that execute the grant_role calls automatically during deployment. This would streamline the workflow and reduce the chance of manual errors. For the metadata_manager role pointing to the Reputation contract, an optional --reputation-contract <ADDRESS> flag could enable automated setup when the address is known.
🤖 Prompt for AI Agents
In `@apps/contract/scripts/deploy-nft.sh` around lines 188 - 201, Add optional CLI
flags (--grant-minter <ADDR>, --grant-burner <ADDR>, --reputation-contract
<ADDR>) to the deploy script and, after successful deployment (when
NFT_CONTRACT_ID and ADMIN_ADDRESS are set), automatically execute the
corresponding grant_role stellar invocations instead of only printing templates:
if --grant-minter provided call stellar contract invoke ... --id
$NFT_CONTRACT_ID -- grant_role --account <ADDR> --role 'minter' --caller
$ADMIN_ADDRESS; similarly for --grant-burner; if --reputation-contract provided
first obtain the metadata_manager role value by invoking stellar contract invoke
... --id $NFT_CONTRACT_ID -- metadata_manager_role and then call grant_role with
--account $REPUTATION_CONTRACT and that role; ensure each invocation checks for
errors and only runs when the respective flag/variable is non-empty.
| read -p "Are you sure you want to continue? (yes/no): " confirm | ||
| if [[ "$confirm" != "yes" ]]; then | ||
| echo "Deployment cancelled." | ||
| exit 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Check if file exists and view the context around lines 124-127
fd deploy-reputation.sh --type fRepository: kindfi-org/kindfi
Length of output: 103
🏁 Script executed:
# Check the content at lines 124-127
if [ -f "apps/contract/scripts/deploy-reputation.sh" ]; then
sed -n '120,130p' "apps/contract/scripts/deploy-reputation.sh"
else
echo "File not found"
fiRepository: kindfi-org/kindfi
Length of output: 388
🌐 Web query:
read -r flag bash shell scripting best practice backslash interpretation
💡 Result:
In Bash, read treats backslash (\) as an escape character by default, which can remove/mangle backslashes (e.g., \a may lose the backslash, and \ before a newline can act like a line-continuation). The -r flag disables this, so backslashes are read literally (“raw”).[1][2]
Best practice: use read -r by default, unless you explicitly want backslash-escape behavior.[1][3]
Typical safe line-reading pattern (preserves leading/trailing whitespace and backslashes):
while IFS= read -r line; do
printf '%s\n' "$line"
done < fileShellCheck also recommends this (SC2162).[1]
Sources: ShellCheck on read -r[1], Bash manual for read -r semantics[2], BashFAQ guidance on “almost always use -r”[3].
References
[1] https://www.shellcheck.net/wiki/SC2162
[2] https://ftp.gnu.org/old-gnu/Manuals/bash/html_node/bashref_55.html
[3] https://mywiki.wooledge.org/BashFAQ/001
Consider adding -r flag to preserve backslashes in user input
Nice safety prompt. The -r flag ensures backslashes aren't interpreted as escape characters, which aligns with shell scripting best practices (ShellCheck SC2162). This is particularly important for confirmation prompts to guarantee you receive exactly what the user typed.
💡 Proposed fix
- read -p "Are you sure you want to continue? (yes/no): " confirm
+ read -r -p "Are you sure you want to continue? (yes/no): " confirm📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| read -p "Are you sure you want to continue? (yes/no): " confirm | |
| if [[ "$confirm" != "yes" ]]; then | |
| echo "Deployment cancelled." | |
| exit 0 | |
| read -r -p "Are you sure you want to continue? (yes/no): " confirm | |
| if [[ "$confirm" != "yes" ]]; then | |
| echo "Deployment cancelled." | |
| exit 0 |
🧰 Tools
🪛 Shellcheck (0.11.0)
[info] 124-124: read without -r will mangle backslashes.
(SC2162)
🤖 Prompt for AI Agents
In `@apps/contract/scripts/deploy-reputation.sh` around lines 124 - 127, The
prompt reading uses read -p "..." confirm which can interpret backslashes;
change it to read -r -p "Are you sure you want to continue? (yes/no): " confirm
so input is read raw and backslashes are preserved (adjust the read invocation
where the prompt and confirm variable are used).
| if [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]] || [[ "$VERIFIED_ADMIN" != "VERIFICATION_FAILED" ]]; then | ||
| echo "Contract admin verified!" | ||
| else | ||
| echo "Warning: Could not verify admin. Contract may still be deployed correctly." | ||
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's find and examine the deploy-reputation.sh file
fd -t f "deploy-reputation.sh" --exec wc -l {} \;Repository: kindfi-org/kindfi
Length of output: 109
🏁 Script executed:
# Read the specific lines in context
cat -n apps/contract/scripts/deploy-reputation.sh | sed -n '175,200p'Repository: kindfi-org/kindfi
Length of output: 1046
🏁 Script executed:
# Search for VERIFIED_ADMIN to understand what values it can contain
rg "VERIFIED_ADMIN" apps/contract/scripts/deploy-reputation.sh -B2 -A2Repository: kindfi-org/kindfi
Length of output: 442
🏁 Script executed:
# Check if VERIFIED_ADMIN is used anywhere else in the script
rg "VERIFIED_ADMIN" apps/contract/scripts/deploy-reputation.shRepository: kindfi-org/kindfi
Length of output: 210
🏁 Script executed:
# Check the complete context after line 189 to see if this is a critical gate
cat -n apps/contract/scripts/deploy-reputation.sh | sed -n '185,250p'Repository: kindfi-org/kindfi
Length of output: 2519
Harden admin verification to avoid false positives
The post-deployment verification step is valuable, but the current logic has a flaw. Using OR conditions means that any output from the get_admin call that isn't literally "VERIFICATION_FAILED" will trigger the "verified!" message—even if the output doesn't contain the expected admin address. If the stellar contract invoke command returns an error or unexpected output, this could create misleading success signals.
We could enhance this by restructuring the conditions to explicitly handle three cases: verification failure, successful admin match, and mismatch. This provides clearer diagnostics and prevents false positives.
💡 Proposed fix
-if [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]] || [[ "$VERIFIED_ADMIN" != "VERIFICATION_FAILED" ]]; then
- echo "Contract admin verified!"
-else
- echo "Warning: Could not verify admin. Contract may still be deployed correctly."
-fi
+if [[ "$VERIFIED_ADMIN" == "VERIFICATION_FAILED" ]]; then
+ echo "Warning: Could not verify admin. Contract may still be deployed correctly."
+elif [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]]; then
+ echo "Contract admin verified!"
+else
+ echo "Warning: Admin mismatch (expected $ADMIN_ADDRESS, got $VERIFIED_ADMIN)."
+fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]] || [[ "$VERIFIED_ADMIN" != "VERIFICATION_FAILED" ]]; then | |
| echo "Contract admin verified!" | |
| else | |
| echo "Warning: Could not verify admin. Contract may still be deployed correctly." | |
| fi | |
| if [[ "$VERIFIED_ADMIN" == "VERIFICATION_FAILED" ]]; then | |
| echo "Warning: Could not verify admin. Contract may still be deployed correctly." | |
| elif [[ "$VERIFIED_ADMIN" == *"$ADMIN_ADDRESS"* ]]; then | |
| echo "Contract admin verified!" | |
| else | |
| echo "Warning: Admin mismatch (expected $ADMIN_ADDRESS, got $VERIFIED_ADMIN)." | |
| fi |
🤖 Prompt for AI Agents
In `@apps/contract/scripts/deploy-reputation.sh` around lines 185 - 189, The
current OR logic with VERIFIED_ADMIN and ADMIN_ADDRESS causes false positives;
change the conditional to explicitly check for three cases: first if
VERIFIED_ADMIN equals "VERIFICATION_FAILED" then treat as verification failure
and echo an error, second if VERIFIED_ADMIN contains the expected ADMIN_ADDRESS
(use the existing pattern match with *"$ADMIN_ADDRESS"*) then echo "Contract
admin verified!", and otherwise echo a clear mismatch warning showing both
VERIFIED_ADMIN and ADMIN_ADDRESS; update the block that references
VERIFIED_ADMIN and ADMIN_ADDRESS accordingly to implement these three branches.
| === Role Assignment Commands === | ||
| # Grant recorder role (can record reputation events): | ||
| stellar contract invoke --network $NETWORK --source $SOURCE --id $REPUTATION_CONTRACT_ID -- grant_role --account <RECORDER_ADDRESS> --role 'recorder' --caller $ADMIN_ADDRESS | ||
|
|
||
| # Grant config role (can update thresholds and point values): | ||
| stellar contract invoke --network $NETWORK --source $SOURCE --id $REPUTATION_CONTRACT_ID -- grant_role --account <CONFIG_ADDRESS> --role 'config' --caller $ADMIN_ADDRESS | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
fd "deploy-reputation.sh" --type fRepository: kindfi-org/kindfi
Length of output: 103
🏁 Script executed:
cat -n apps/contract/scripts/deploy-reputation.shRepository: kindfi-org/kindfi
Length of output: 12444
Consider automating initial recorder/config role grants with optional flags
The script provides useful template grant commands for recorder/config roles. We could enhance this by adding optional flags (e.g., --grant-recorder <ADDRESS> and --grant-config <ADDRESS>) to execute these grants automatically during deployment, following the same pattern as the existing --nft-contract option. This would streamline the deployment workflow by eliminating the need for manual post-deployment role assignment.
🤖 Prompt for AI Agents
In `@apps/contract/scripts/deploy-reputation.sh` around lines 256 - 262, Add
optional CLI flags --grant-recorder <ADDRESS> and --grant-config <ADDRESS> to
the deploy-reputation.sh argument parsing, and if provided invoke the same
grant_role commands shown in the template using the existing variables (NETWORK,
SOURCE, REPUTATION_CONTRACT_ID, ADMIN_ADDRESS) to run: stellar contract invoke
... --grant_role --account <ADDRESS> --role 'recorder' (or 'config') --caller
$ADMIN_ADDRESS; ensure flags are parsed where other options like --nft-contract
are handled and that the commands only run when the corresponding variable
(e.g., GRANT_RECORDER, GRANT_CONFIG) is non-empty, with error handling/logging
on failure.
Bran18
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great deployment scripts. I noticed you’re using the smart-account–related one as the foundation, which is very handy for our development.
I also helped resolve a few conflicts between feat/scripts-nft-reputation and develop, mainly related to the Cargo.lock. This branch is now ready to be merged.
* feat: add didit KYC user flow (#768) * feat: add dididt KYC user flow * fix: build issues * fix(auth): add pending role state and fix user signup default role * chore: generate Supabase types from remote instance * fix: configure Vercel for monorepo and add Supabase types * feat: kindfi nft open zeppelin (#769) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: Reputation Contract for NFT Level Management (#773) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: Comprehensive Tests and Integration for NFT & Reputation Contracts (#774) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation * test(reputation): add reputation contract tests * test(nft): add NFT contract tests --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: Deployment Scripts and Configuration for NFT & Reputation Contracts (#775) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation * test(reputation): add reputation contract tests * test(nft): add NFT contract tests * chore: update cargo lock file * docs: update contracts README * script: add NFT contract deployment script * script: add reputation contract deployment script * chore: add environment example file --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: refactor nft-kindfi with SEP-0050 compatibility (#778) * feat: add SEP-0050 compliant NFTAttribute struct to nft-kindfi types Replace Vec<String> attributes with Vec<NFTAttribute> using structured fields (trait_type, value, display_type, max_value) to comply with the SEP-0050 Non-Fungible Metadata JSON Schema. * feat: update nft-kindfi tests to use NFTAttribute struct Adapt all test helpers and test cases to use the new SEP-0050 compliant NFTAttribute struct instead of plain strings for metadata attributes. * feat: update reputation nft_client to SEP-0050 attribute format Refactor NFTMetadata mirror and level attribute helpers to use the new NFTAttribute struct. Update cross-contract call types and all related tests for SEP-0050 compliance. * fix(kyc): prevent URL params cleanup on failure and add error toasts (#777) * fix(kyc): prevent URL params cleanup on failure and add error toasts * refactor(kyc): deduplicate error message string per code review * fix(kyc): sync with develop and add error logging per code review * refactor: centralize didit kyc status mapping logic (#779) * refactor: centralize didit kyc status mapping logic * refactor: apply code review feedback (arrow functions, type-only imports, and alias paths) * style(ui): use bg-primary token instead of hex code in progress bar (#780) Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * chore: add vercel skills set for OSS * fix: add new migration strategy * feat: add fundation support * chore: generate Supabase database types using MCP tool - Generated complete TypeScript types from Supabase database - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> * fix: add complete Supabase database types - Generated TypeScript types from Supabase database using MCP tool - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> * fix: add complete Supabase database types - Generated TypeScript types from Supabase database using MCP tool - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Matias Aguilar <aaguilar1x@gmail.com> Co-authored-by: Karen Giannetto <karengiannetto99@gmail.com> Co-authored-by: Delfina luna Corradini <105253541+delfinacorr@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: add didit KYC user flow (#768) * feat: add dididt KYC user flow * fix: build issues * fix(auth): add pending role state and fix user signup default role * chore: generate Supabase types from remote instance * fix: configure Vercel for monorepo and add Supabase types * feat: kindfi nft open zeppelin (#769) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: Reputation Contract for NFT Level Management (#773) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: Comprehensive Tests and Integration for NFT & Reputation Contracts (#774) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation * test(reputation): add reputation contract tests * test(nft): add NFT contract tests --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: Deployment Scripts and Configuration for NFT & Reputation Contracts (#775) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation * test(reputation): add reputation contract tests * test(nft): add NFT contract tests * chore: update cargo lock file * docs: update contracts README * script: add NFT contract deployment script * script: add reputation contract deployment script * chore: add environment example file --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: refactor nft-kindfi with SEP-0050 compatibility (#778) * feat: add SEP-0050 compliant NFTAttribute struct to nft-kindfi types Replace Vec<String> attributes with Vec<NFTAttribute> using structured fields (trait_type, value, display_type, max_value) to comply with the SEP-0050 Non-Fungible Metadata JSON Schema. * feat: update nft-kindfi tests to use NFTAttribute struct Adapt all test helpers and test cases to use the new SEP-0050 compliant NFTAttribute struct instead of plain strings for metadata attributes. * feat: update reputation nft_client to SEP-0050 attribute format Refactor NFTMetadata mirror and level attribute helpers to use the new NFTAttribute struct. Update cross-contract call types and all related tests for SEP-0050 compliance. * fix(kyc): prevent URL params cleanup on failure and add error toasts (#777) * fix(kyc): prevent URL params cleanup on failure and add error toasts * refactor(kyc): deduplicate error message string per code review * fix(kyc): sync with develop and add error logging per code review * refactor: centralize didit kyc status mapping logic (#779) * refactor: centralize didit kyc status mapping logic * refactor: apply code review feedback (arrow functions, type-only imports, and alias paths) * style(ui): use bg-primary token instead of hex code in progress bar (#780) Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * chore: add vercel skills set for OSS * fix: add new migration strategy * feat: add fundation support * chore: generate Supabase database types using MCP tool - Generated complete TypeScript types from Supabase database - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> * fix: add complete Supabase database types - Generated TypeScript types from Supabase database using MCP tool - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> * fix: add complete Supabase database types - Generated TypeScript types from Supabase database using MCP tool - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> * Fix: WebAuthn cross environments --------- Co-authored-by: Matias Aguilar <aaguilar1x@gmail.com> Co-authored-by: Karen Giannetto <karengiannetto99@gmail.com> Co-authored-by: Delfina luna Corradini <105253541+delfinacorr@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: add didit KYC user flow (#768) * feat: add dididt KYC user flow * fix: build issues * fix(auth): add pending role state and fix user signup default role * chore: generate Supabase types from remote instance * fix: configure Vercel for monorepo and add Supabase types * feat: kindfi nft open zeppelin (#769) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: Reputation Contract for NFT Level Management (#773) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: Comprehensive Tests and Integration for NFT & Reputation Contracts (#774) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation * test(reputation): add reputation contract tests * test(nft): add NFT contract tests --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: Deployment Scripts and Configuration for NFT & Reputation Contracts (#775) * feat: add KindFi NFT contract structure and types - Add Cargo.toml for nft-kindfi contract with OpenZeppelin dependencies - Add types.rs with NFTMetadata struct and StorageKey enum - Add errors.rs with custom error definitions - Add events.rs with metadata update events * feat: implement KindFi NFT core functionality - Add lib.rs with main contract implementing NonFungibleToken, AccessControl, and custom metadata functions - Add metadata.rs for on-chain metadata storage and retrieval - Add mint.rs for sequential token ID minting with metadata - Add burn.rs for token burning functionality - Implement role-based access control (minter, burner, metadata_manager) - Add OpenZeppelin Stellar Contracts integration * fix: update workspace members for compilation - Comment out non-existent contract members to allow compilation - Add nft-kindfi to implemented contracts - Reorganize workspace members with clear sections * chore: update Cargo.lock with new contract dependencies * feat: update to OpenZeppelin Stellar Contracts v0.6.0 - Update soroban-sdk from 22.0.6 to 23.4.0 - Update all OpenZeppelin dependencies from v0.3.0 to v0.6.0 - Restructure dependencies: stellar-access-control → stellar-access, stellar-non-fungible → stellar-tokens * feat: update nft-kindfi dependencies for v0.6.0 - Update contract dependencies to use new package structure - stellar-access-control → stellar-access - stellar-access-control-macros → stellar-macros - stellar-non-fungible → stellar-tokens * refactor: update imports for OpenZeppelin v0.6.0 - Update stellar_access_control imports to stellar_access::access_control - Update stellar_non_fungible imports to stellar_tokens::non_fungible - Update stellar_access_control_macros to stellar_macros - Fix AccessControl trait method signatures to match v0.6.0 API * chore: kindfi information in the workspace.package and comments added in members * fix: target changed to wasm32v1-none and leaving necessary components * chore: Add additional information about kindfi to contract cargo.toml and change crate-type to just (cdylib) * fix: config.toml file removed since it generated conflicts with rust base and the tests did not compile * refactor: change in the use of events, since due to the sdk update they are now used with the contractevent and topic macro * refactor: structure change in the use of events of the form .publish(e) for the different files that propagate the events * doc: detailed documentation about the nft-kindfi contract * chore: add admin.require_auth() add admin.require_auth() for validation and security of contract initialization * fix: validation was added for the metadata and the event was created to send this * feat: add root cargo manifest for contracts workspace * feat(reputation): add cargo manifest for reputation contract * feat(reputation): add reputation contract main library * feat(reputation): add reputation contract types and data structures * feat(reputation): add reputation contract storage layer * feat(reputation): add reputation contract error types * feat(reputation): add reputation contract events * feat(reputation): add NFT client integration for reputation contract * docs(reputation): add reputation contract documentation * test(reputation): add reputation contract tests * test(nft): add NFT contract tests * chore: update cargo lock file * docs: update contracts README * script: add NFT contract deployment script * script: add reputation contract deployment script * chore: add environment example file --------- Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * feat: refactor nft-kindfi with SEP-0050 compatibility (#778) * feat: add SEP-0050 compliant NFTAttribute struct to nft-kindfi types Replace Vec<String> attributes with Vec<NFTAttribute> using structured fields (trait_type, value, display_type, max_value) to comply with the SEP-0050 Non-Fungible Metadata JSON Schema. * feat: update nft-kindfi tests to use NFTAttribute struct Adapt all test helpers and test cases to use the new SEP-0050 compliant NFTAttribute struct instead of plain strings for metadata attributes. * feat: update reputation nft_client to SEP-0050 attribute format Refactor NFTMetadata mirror and level attribute helpers to use the new NFTAttribute struct. Update cross-contract call types and all related tests for SEP-0050 compliance. * fix(kyc): prevent URL params cleanup on failure and add error toasts (#777) * fix(kyc): prevent URL params cleanup on failure and add error toasts * refactor(kyc): deduplicate error message string per code review * fix(kyc): sync with develop and add error logging per code review * refactor: centralize didit kyc status mapping logic (#779) * refactor: centralize didit kyc status mapping logic * refactor: apply code review feedback (arrow functions, type-only imports, and alias paths) * style(ui): use bg-primary token instead of hex code in progress bar (#780) Co-authored-by: Brandon Fernández <31634868+Bran18@users.noreply.github.com> * chore: add vercel skills set for OSS * fix: add new migration strategy * feat: add fundation support * chore: generate Supabase database types using MCP tool - Generated complete TypeScript types from Supabase database - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> * fix: add complete Supabase database types - Generated TypeScript types from Supabase database using MCP tool - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> * fix: add complete Supabase database types - Generated TypeScript types from Supabase database using MCP tool - Includes all tables, enums, functions, and relationships - Fixes Vercel build error: Module '@services/supabase' has no exported member 'Database' Co-authored-by: Cursor <cursoragent@cursor.com> * Fix: WebAuthn cross environments * Fix: WebAuthn non dynamic * Fix: add path alias --------- Co-authored-by: Matias Aguilar <aaguilar1x@gmail.com> Co-authored-by: Karen Giannetto <karengiannetto99@gmail.com> Co-authored-by: Delfina luna Corradini <105253541+delfinacorr@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Deployment Scripts
scripts/deploy-nft.sh--testnet,--futurenet,--mainnet--source,--admin,--name,--symbol,--base-urinft-deployment-info-<network>.txtscripts/deploy-reputation.sh--testnet,--futurenet,--mainnet--source,--admin,--nft-contractreputation-deployment-info-<network>.txtConfiguration
.env.exampleDocumentation
README.md updated with:
Quick Start