Debt & asset finance https://docs.hazbase.com/en/patterns/finance/ IMPLEMENTATION PATTERNS Debt & asset finance Model distinct rights and connect repayment, distributions and records. ← All implementation patterns EXAMPLE Issue equipment-finance positions and reconcile repayments Track positions in an equipment business separately when maturity or payment terms differ. Map BondToken classId to a category of terms and nonceId to an issuance series or maturity, then record each investor’s units. Build a view connecting agreement terms, issuance series, investor holdings, payment schedules and actual receipts. Architecture and responsibilities 0 1 Agreements and investors Manage agreement originals, investor eligibility and payment schedules. Application API / DB 0 2 Positions and holdings Track issuance and holdings for each classId and nonceId pair. BondTokenHelper 0 3 Payments and claims Reconcile bank transfers or connect token-based claim processing as appropriate. Bank integration / DebtManagerHelper 0 4 Operations and reporting Store holdings at the record date and payment outcomes for reporting. Snapshots / Application ledger Example data model Map application records to the data managed by the chain or APIs. Field names and values below illustrate the application model for this architecture. Field and example Stored in Purpose and mapping agreementId / termsVersion FIN-001 / v1 Application DB Identify principal, dates, equipment and the agreement version. classId 20 Chain and DB mapping Category of rights or terms, defined by the application. nonceId 202709 Chain and DB mapping An issuance series within a class, distinct from signature replay-protection nonces. investor / units investorWallet / 10 Chain Holdings are integer units. The agreement defines the amount and currency per unit. paymentId / recordDate PAY-2027-09 / timestamp Application DB Identify the payment and record date, retaining the snapshot ID or block used. bankReference / transactionHash bank-ref / 0x… Application DB Record bank transfers and chain transactions as separate evidence. Processing flow 1 Map terms to a class and series Map FIN-001 to classId 20 and its series to nonceId 202709. Create both identifiers and include only public metadata on chain. createClass(classId, data) → createNonce(classId, nonceId, data) 2 Issue after eligibility and funding checks Check identity, agreement and funding in the application. Configure any required allowlist, then issue 10 units. Token issuance does not itself verify a bank deposit. issue(investor, classId, nonceId, 10n) 3 Fix holdings at the record date Associate payment entitlement with holdings at the contractual record date, not the current balance at payment time. BondToken snapshots are created when called; they cannot retroactively create a snapshot for an arbitrary date. snapshot() → balanceOfAt(holder, classId, nonceId, snapshotId) 4 Connect the payment path For bank transfers, reconcile amounts and receipts in the application ledger. With DebtManager, configure BondToken, principal and coupon tokens, permissions and schedules, then fund the coupon using payCoupon. DebtManager: createTranche → addCouponSchedule → payCoupon → claimCoupon 5 Reconcile redemption and records Reconcile principal repayment with retiring units. BondToken redeem burns units; linking that action to a payout requires a payment workflow such as DebtManager. BondToken.redeem / DebtManager.redeemAtMaturity Before using the code Provide an initialized BondToken, an existing classId and nonceId, and a signer with MINTER_ROLE. Pass position units as bigint. Distinguish these units from ERC-20 amounts with decimals. Complete eligibility, agreement and funding checks, including any required allowlisting, before calling. Install npm install --save-exact @hazbase/kit@0.9.0 ethers@6.16.0 The TypeScript functions below are called from your application with the appropriate connections, permissions and data. Integrate the UI, persistence and recovery using the architecture above. Allocate a position in a specific series Use classId: 20n, nonceId: 202709n and units: 10n. agreementId is your application’s agreement ID, included in the result for ledger persistence. pattern-finance.ts 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import { BondTokenHelper } from '@hazbase/kit' ; type Signer = Parameters < typeof BondTokenHelper . deploy > [ 1 ] ; export async function allocateBond ( input : { agreementId : string ; tokenAddress : string ; classId : bigint ; nonceId : bigint ; investor : string ; units : bigint ; issuer : Signer ; } ) { // The class and nonce must already exist; issuer needs MINTER_ROLE. if ( input . units <= 0n ) throw new Error ( 'Units must be positive.' ) ; const bond = BondTokenHelper . attach ( input . tokenAddress , input . issuer ) ; const receipt = await bond . issue ( input . investor , input . classId , input . nonceId , input . units , ) ; const balance = await bond . balanceOf ( input . investor , input . classId , input . nonceId , ) ; return { agreementId : input . agreementId , classId : input . classId . toString ( ) , nonceId : input . nonceId . toString ( ) , investor : input . investor , issuedUnits : input . units . toString ( ) , balance : balance . toString ( ) , transactionHash : receipt . hash , } ; } Download the example Result and application integration The investor’s balance for the class and nonce increases and a transaction hash is returned. This operation does not move money. Reconcile funding confirmation and issuance using the agreement ID. Implementation considerations Coupon record dates DebtManager payCoupon uses a snapshot taken at execution. If entitlement belongs to holders at an earlier record date, use a workflow matching that record rather than distributing to current holders. Currencies, decimals and rounding Distinguish principal currency, coupon-token decimals and amount per unit. Align rounding and residual handling between the ledger and contract calculations. Permissions and funding DebtManager needs the necessary BondToken permissions plus payment-token balances and allowances. Keep insufficient-funding and overdue states distinct from paid. Extending the architecture Fixed routes versus holder distributions Splitter routes funds to configured recipients and ratios; it does not enumerate token holders for dividends. Separate fixed counterparty splits from record-date holder distributions. Working with Fund Ops Fund Ops serves fund operators investing in RWAs, particularly asset finance. Map its scope to your own agreement and investor-management systems when integrating. Related API and SDK reference BondTokenHelper DebtManagerHelper SplitterHelper Start with the sample application Deployment and operations