account_id matches the NFT’s token_id, and the NFT holder owns the account.
The controller resolves ownership through owner_of when a call requires
account authority.
Identifiers and lifecycle
The controller API usesu64 account ids, while NFT token ids use u32. The
account-id space is therefore bounded by u32. Token id 0 is consumed during
construction and cannot represent a lending account.
Keep account ids as decimal strings in JavaScript. The SDK’s accountNonce is
this lending id; sourceSequence is the Stellar transaction source sequence.
They are independent. Convert to u32 with a range check when calling NFT views.
Supported controller flows use account_id = 0 to create an account, including
supply, multiply, flash_position, migrate_from_blend, and liquidation
SeizeMode::Credit(0). Creation mints the NFT; account deletion burns it.
Withdrawal and strategy paths can delete an account when no supply or debt
remains. Liquidation and bad-debt cleanup have their own deletion paths.
Repayment alone updates debt and does not delete an empty account. Reconcile
account_exists(account_id) after an operation that can close it. Clear a stored
id only after an explicit false; abort on a failed lookup.
The controller owns the NFT contract. Governance deploys it through
DeployPositionNft and upgrades it through UpgradePositionNft(hash). Account
creation without a configured NFT fails with #53 PositionNftNotSet.
Existing-account authority checks fail closed if NFT ownership cannot be
resolved, usually with #24 AccountNotFound. Metadata-only views need no NFT
lookup.
Protocol interface
The controller’s
renew_account requires the account owner’s authorization and
renews the controller instance, account records, and NFT owner/balance entries.
Direct NFT renew remains permissionless and renews NFT state only. Neither
call renews the integrating contract’s local account-id key.
See Storage.
Transfer and approvals
The contract implements OpenZeppelin’s enumerable non-fungible token interface:
A transfer preserves collateral, debt, spoke binding, position mode, and stored
risk parameters. The previous owner’s delegate grants become inactive while
another address owns the token. They can reactivate if it returns before those
grants are replaced. See
Delegates for grant lifecycle.
The new owner can call
remove_delegate to delete a stale grant. This can delete
the previous owner’s stored grant without a delegate-change event, because the
current owner’s delegate list did not change. Adding a delegate replaces stale
grants with the new owner’s list. A reactivated delegate must also remain an active,
registered position manager.
Enumeration and metadata
The URI format is
{base_uri}{token_id}?isStatic=true&chain=STELLAR.
token_uri fails with OpenZeppelin NonExistentToken for burned or never-minted
ids.
Use Addresses to resolve the NFT contract and
Controller ABI for lending calls.
