Leo programs for batching record consolidation on Aleo before executing a transfer, for both native credits.aleo and stablecoins (usad, usdcx).
Three contract families, differentiated by the underlying asset and the recipient semantics of the final call:
| Family | Directory | Final call | Recipient | Backing asset(s) |
|---|---|---|---|---|
| Private transfer | private_transfer/ |
transfer_private |
arbitrary address (parameter) | credits.aleo, usad_stablecoin.aleo, usdcx_stablecoin.aleo |
| Self transfer to public | self_transfer_private_to_public/ |
transfer_private_to_public |
self.signer (caller only) |
credits.aleo |
| Transfer to public | transfer_private_to_public/ |
transfer_private_to_public |
arbitrary address (public parameter) | usad_stablecoin.aleo, usdcx_stablecoin.aleo |
Within each family, programs are further split by record-count range because Leo limits function size by constraint count. credits.aleo-backed programs cover 2–14 records (split 2–8 / 9–10 / 11–14);
stablecoin-backed programs cover 2–13 records (split 2–8 / 9–10 / 11–13).
private_transfer transitions (transfer_private_N):
- Take N
credits.aleo::creditsrecords - Join them into a single record via repeated
credits.aleo::joincalls - Call
credits.aleo::transfer_private(joined_record, recipient, amount) - Return
(change: credits, output: credits)- noFinalblock; the transition is fully private
self_transfer_private_to_public transitions (transfer_private_to_public_N):
- Take N
credits.aleo::creditsrecords and apublic amount: u64 - Join them into a single record
- Call
credits.aleo::transfer_private_to_public(joined_record, self.signer, amount) - Return
(change: credits, Final)-Finalexecutes the on-chain balance update, always crediting the caller
private_transfer transitions (transfer_private_N):
- Take N
<token>.aleo::Tokenrecords, arecipient: address,amount: u128, and aproofs: [<token>.aleo::MerkleProof; 2]compliance proof - Join the records, then call
<token>.aleo::transfer_private(recipient, amount, joined_record, proofs) - Return
(ComplianceRecord, change: Token, output: Token, Final)-Finalruns compliance/finalize logic even though the transfer itself stays private
transfer_private_to_public transitions (transfer_private_to_public_N):
- Take N
<token>.aleo::Tokenrecords, apublic recipient: address,public amount: u128, andproofs - Join the records, then call
<token>.aleo::transfer_private_to_public(recipient, amount, joined_record, proofs) - Return
(ComplianceRecord, change: Token, Final) - Unlike the
credits.aleoself-transfer family,recipientis a free parameter, notself.signer- hence these programs live undertransfer_private_to_public/rather thanself_transfer_private_to_public/
external/
credits.aleo # credits.aleo program source (reference)
token_registry.aleo # token_registry.aleo program source (reference)
private_transfer/ # transfer_private, arbitrary recipient
ldgbatcher_2_8_records/ # ldg_p_28.aleo credits.aleo (transitions 2-8)
ldgbatcher_9_10_records/ # ldg_p_910.aleo credits.aleo (transitions 9-10)
ldgbatcher_11_14_records/ # ldg_p_1114.aleo credits.aleo (transitions 11-14)
usad_ldgbatcher_28_records/ # ldg_usad_p_28.aleo usad_stablecoin.aleo (transitions 2-8)
usad_ldgbatcher_910_records/ # ldg_usad_p_910.aleo usad_stablecoin.aleo (transitions 9-10)
usad_ldgbatcher_1113_records/ # ldg_usad_p_1113.aleo usad_stablecoin.aleo (transitions 11-13)
usdcx_ldgbatcher_28_records/ # ldg_usdcx_p_28.aleo usdcx_stablecoin.aleo (transitions 2-8)
usdcx_ldgbatcher_910_records/ # ldg_usdcx_p_910.aleo usdcx_stablecoin.aleo (transitions 9-10)
usdcx_ldgbatcher_1113_records/ # ldg_usdcx_p_1113.aleo usdcx_stablecoin.aleo (transitions 11-13)
self_transfer_private_to_public/ # transfer_private_to_public, recipient = self.signer
ldgbatcher_2_8_records/ # ldg_p2p_28.aleo credits.aleo (transitions 2-8)
ldgbatcher_9_10_records/ # ldg_p2p_910.aleo credits.aleo (transitions 9-10)
ldgbatcher_11_14_records/ # ldg_p2p_1114.aleo credits.aleo (transitions 11-14)
transfer_private_to_public/ # transfer_private_to_public, arbitrary recipient
usad_ldgbatcher_ppub_28_records/ # ldg_usad_p2p_28.aleo usad_stablecoin.aleo (transitions 2-8)
usad_ldgbatcher_ppub_910_records/ # ldg_usad_p2p_910.aleo usad_stablecoin.aleo (transitions 9-10)
usad_ldgbatcher_ppub_1113_records/ # ldg_usad_p2p_1113.aleo usad_stablecoin.aleo (transitions 11-13)
usdcx_ldgbatcher_ppub_28_records/ # ldg_usdcx_p2p_28.aleo usdcx_stablecoin.aleo (transitions 2-8)
usdcx_ldgbatcher_ppub_910_records/ # ldg_usdcx_p2p_910.aleo usdcx_stablecoin.aleo (transitions 9-10)
usdcx_ldgbatcher_ppub_1113_records/ # ldg_usdcx_p2p_1113.aleo usdcx_stablecoin.aleo (transitions 11-13)
Each program directory contains:
src/main.leo- program sourceprogram.json- Leo project manifest (name, version, dependencies).env.example- environment variable template (see Deploy)build/,outputs/- generated build/execution artifacts once you runleo build/leo execute(git-ignored)
- Leo ≥ 4.0 (
leo --version)
From any program directory (e.g. to build the 2–8 private-transfer program):
cd private_transfer/ldgbatcher_2_8_records
leo buildRepeat for each program you intend to deploy, e.g.:
cd private_transfer/ldgbatcher_9_10_records && leo build
cd private_transfer/ldgbatcher_11_14_records && leo build
cd private_transfer/usad_ldgbatcher_28_records && leo build
cd private_transfer/usad_ldgbatcher_910_records && leo build
cd private_transfer/usad_ldgbatcher_1113_records && leo build
cd private_transfer/usdcx_ldgbatcher_28_records && leo build
cd private_transfer/usdcx_ldgbatcher_910_records && leo build
cd private_transfer/usdcx_ldgbatcher_1113_records && leo build
cd self_transfer_private_to_public/ldgbatcher_2_8_records && leo build
cd self_transfer_private_to_public/ldgbatcher_9_10_records && leo build
cd self_transfer_private_to_public/ldgbatcher_11_14_records && leo build
cd transfer_private_to_public/usad_ldgbatcher_ppub_28_records && leo build
cd transfer_private_to_public/usad_ldgbatcher_ppub_910_records && leo build
cd transfer_private_to_public/usad_ldgbatcher_ppub_1113_records && leo build
cd transfer_private_to_public/usdcx_ldgbatcher_ppub_28_records && leo build
cd transfer_private_to_public/usdcx_ldgbatcher_ppub_910_records && leo build
cd transfer_private_to_public/usdcx_ldgbatcher_ppub_1113_records && leo build-
Create a
.envinside the program directory (copy.env.examplewhere one exists, otherwise create it directly) and fill in your credentials:cp .env.example .env
NETWORK=testnet PRIVATE_KEY=APrivateKey1... ENDPOINT=https://api.explorer.provable.com/v1
-
Deploy from the program directory (to testnet):
leo deploy --print --network testnet --broadcast
Leo reads NETWORK, PRIVATE_KEY, and ENDPOINT from .env and submits the deployment transaction.
All programs resolve their dependency directly from the network (declared in program.json) - no local path overrides are needed:
credits.aleo-backed programs (private_transfer/ldgbatcher_*,self_transfer_private_to_public/ldgbatcher_*) depend oncredits.aleo.- Stablecoin-backed programs (
*_ldgbatcher(_ppub)_*underprivate_transfer/andtransfer_private_to_public/) depend onusad_stablecoin.aleoorusdcx_stablecoin.aleo
Reference copies of the credits.aleo and token_registry.aleo program source live under external/ for lookup; they are not built or deployed from this repo.