Skip to main content

sla_escrow_api/
consts.rs

1//! Shared on-chain and SDK defaults for sla-escrow (grouped by concern).
2
3use const_crypto::ed25519;
4use solana_program::{pubkey, pubkey::Pubkey};
5
6// =============================================================================
7// Authority
8// =============================================================================
9
10// Account allowed to invoke [`Initialize`](crate::instruction::EscrowInstruction::Initialize).
11// DEVNET
12// pub const INITIALIZER_ADDRESS: Pubkey = pubkey!("4ALL9EAVHpv7ioJF95ktDLtrHUEJezPuFxTFFMy3fpSy");
13// MAINNET
14pub const INITIALIZER_ADDRESS: Pubkey = pubkey!("CD6SkYqR8TRjSaPmmyRUc7J4PhoQdhS8E4r7KjWxxJFW");
15
16// =============================================================================
17// Fees, oracle tip cap, and `open_escrow` amount defaults (USDC-style 6 decimals)
18// =============================================================================
19
20/// Basis points denominator (1 bp = 0.01%).
21pub const BASIS_POINTS_DENOMINATOR: u128 = 10_000;
22
23/// Default bank protocol fee at `Initialize` when not overridden.
24pub const DEFAULT_FEE_BPS: u16 = 100; // 1%
25
26/// Program-enforced cap on protocol `fee_bps` (used by `Initialize`,
27/// `OpenEscrow`, `UpdateEscrowSettings`). 10% ceiling.
28pub const MAX_FEE_BASIS_POINTS: u16 = 1_000;
29
30/// Cap on per-escrow oracle tip (`oracle_fee_bps`).
31pub const MAX_ORACLE_FEE_BPS: u16 = 500;
32
33/// Default minimum protocol fee at release (raw units); `max(bps_fee, min_fee_amount)`.
34pub const DEFAULT_MIN_FEE_RAW_USDC_DECIMALS_6: u64 = 100_000;
35
36/// Default minimum payment (raw) for `open_escrow` USDC-style defaults; must exceed min fee above.
37pub const DEFAULT_MIN_PAYMENT_RAW_USDC_DECIMALS_6: u64 = 1_000_000;
38
39// =============================================================================
40// Global `Config`: defaults at `Initialize`
41// =============================================================================
42
43/// Default `Config::closure_delay_seconds` (post-settlement retention before `close-payment`).
44pub const CLOSURE_DELAY_RELEASE_REFUND: i64 = 7 * 24 * 60 * 60; // 7 days
45
46/// Default `Config::refund_cooldown_seconds` (spacing for buyer-initiated refunds).
47/// Shorter than legacy 48h — tuned for agentic / high-throughput flows; raise via `update-config` if needed.
48pub const DEFAULT_REFUND_COOLDOWN_SECONDS: i64 = 24 * 60 * 60; // 24 hours
49
50/// Default `Config::delivery_cutoff_seconds` (oracle evaluation window before expiry).
51pub const DEFAULT_DELIVERY_CUTOFF_SECONDS: i64 = 300; // 5 minutes
52
53// =============================================================================
54// Global `Config`: bounds for `UpdateConfig` (validator in `update_config.rs`)
55// =============================================================================
56
57/// Minimum allowed `closure_delay_seconds` (agent-friendly floor).
58pub const MIN_CLOSURE_DELAY_SECONDS: i64 = 5 * 60; // 5 minutes
59
60/// Maximum allowed `closure_delay_seconds`.
61pub const MAX_CLOSURE_DELAY_SECONDS: i64 = 30 * 24 * 60 * 60; // 30 days
62
63/// When refund cooldown is enabled (`> 0`), minimum allowed value.
64pub const MIN_REFUND_COOLDOWN_WHEN_ENABLED_SECONDS: i64 = 60 * 60; // 1 hour
65
66/// Maximum allowed refund cooldown.
67pub const MAX_REFUND_COOLDOWN_SECONDS: i64 = 7 * 24 * 60 * 60; // 7 days
68
69/// Maximum allowed `delivery_cutoff_seconds`.
70pub const MAX_DELIVERY_CUTOFF_SECONDS: i64 = 24 * 60 * 60; // 1 day
71
72// =============================================================================
73// Payment TTL (`FundPayment`, `ExtendPaymentTTL`)
74// =============================================================================
75
76/// Program-enforced minimum TTL for a funded payment.
77pub const MIN_TTL_SECONDS: i64 = 60; // 1 minute
78
79/// Default TTL when using `fund-payment` without `--ttl-seconds` (CLI and integrators).
80pub const DEFAULT_TTL_SECONDS: i64 = 24 * 60 * 60; // 86400 s = 24 hours
81
82/// Program-enforced maximum TTL from funding time.
83pub const MAX_TTL_SECONDS: i64 = 30 * 24 * 60 * 60; // 30 days
84
85// =============================================================================
86// Payment state bytes
87// =============================================================================
88
89pub const PAYMENT_STATE_FUNDED: u8 = 0; // Account created and funded atomically
90pub const PAYMENT_STATE_RELEASED: u8 = 1; // Released to seller (normal flow)
91pub const PAYMENT_STATE_REFUNDED: u8 = 2; // Refunded to buyer (normal flow)
92
93// =============================================================================
94// PDA seeds
95// =============================================================================
96
97/// Seed for the bank PDA.
98pub const BANK: &[u8] = b"bank";
99
100/// Seed for the config PDA.
101pub const CONFIG: &[u8] = b"config";
102
103/// Seed for per-mint escrow PDAs.
104pub const ESCROW: &[u8] = b"escrow";
105
106/// Seed for native SOL liquidity storage (SOL escrows).
107pub const SOL_STORAGE: &[u8] = b"sol_storage";
108
109/// Seed for payment PDAs.
110pub const PAYMENT: &[u8] = b"payment";
111
112/// Seed for the authority transfer proposal PDA.
113pub const AUTHORITY_TRANSFER: &[u8] = b"authority_transfer";
114
115// =============================================================================
116// Authority transfer timelock (compile-time immutable — cannot be shortened by
117// a compromised bank authority; only changeable via program upgrade)
118// =============================================================================
119
120// Mandatory delay before a proposed authority transfer can be accepted (in seconds).
121// Production value: 2 days (48 hours = 2 * 24 * 60 * 60)
122pub const AUTHORITY_TRANSFER_DELAY_SECONDS: i64 = 172_800;
123
124// Mandatory delay between an `UpdateAuthority` proposal and `AcceptAuthority`
125// (seconds). Compile-time constant — cannot be shortened by a compromised
126// bank authority; only changeable via program upgrade. Devnet: 180 s.
127// pub const AUTHORITY_TRANSFER_DELAY_SECONDS: i64 = 180;
128
129// =============================================================================
130// Well-known token mints (mainnet-style symbols; devnet may use other mints)
131// =============================================================================
132
133pub const MARS_MINT_ADDRESS: Pubkey = pubkey!("7RAV5UPRTzxn46kLeA8MiJsdNy9VKc5fip8FWEgTpTHh");
134pub const USDC_MINT_ADDRESS: Pubkey = pubkey!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
135pub const USDT_MINT_ADDRESS: Pubkey = pubkey!("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
136pub const WSOL_MINT_ADDRESS: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
137pub const MIRACLE_MINT_ADDRESS: Pubkey = pubkey!("Mirab4SFVff6sCuK48PPnSUj7PNpDDrBWY6FkJmuifG");
138pub const TESTCOIN_MINT_ADDRESS: Pubkey = pubkey!("2gNCDGj8Xi9Zs7LNQTPWf4pfZvAM7UHusY4xhKNYg6W6");
139
140/// SPL Token-2022 program id.
141pub const TOKEN_2022_PROGRAM_ID: Pubkey = pubkey!("TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb");
142
143// =============================================================================
144// Derived addresses for this program id (compile-time; off-chain convenience)
145// =============================================================================
146
147const PROGRAM_ID: [u8; 32] = unsafe { *(&crate::id() as *const Pubkey as *const [u8; 32]) };
148
149/// Bank PDA for [`crate::ID`].
150pub const BANK_ADDRESS: Pubkey =
151    Pubkey::new_from_array(ed25519::derive_program_address(&[BANK], &PROGRAM_ID).0);
152
153/// Config PDA for [`crate::ID`].
154pub const CONFIG_ADDRESS: Pubkey =
155    Pubkey::new_from_array(ed25519::derive_program_address(&[CONFIG], &PROGRAM_ID).0);
156
157/// Precomputed escrow-related PDAs for this program id (integrator convenience).
158///
159/// These are **compile-time constants** in the API crate only—they are **not** stored in the
160/// on-chain program account data and do **not** increase Solana program deployment size or rent.
161pub const MARS_ESCROW_ADDRESS: Pubkey = Pubkey::new_from_array(
162    ed25519::derive_program_address(
163        &[
164            ESCROW,
165            unsafe { &*(&MARS_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
166            unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
167        ],
168        &PROGRAM_ID,
169    )
170    .0,
171);
172pub const MARS_ESCROW_BUMP: u8 = ed25519::derive_program_address(
173    &[
174        ESCROW,
175        unsafe { &*(&MARS_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
176        unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
177    ],
178    &PROGRAM_ID,
179)
180.1;
181pub const MARS_ESCROW_TOKENS_ADDRESS: Pubkey = Pubkey::new_from_array(
182    ed25519::derive_program_address(
183        &[
184            unsafe { &*(&MARS_ESCROW_ADDRESS as *const Pubkey as *const [u8; 32]) },
185            unsafe { &*(&spl_token::id() as *const Pubkey as *const [u8; 32]) },
186            unsafe { &*(&MARS_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
187        ],
188        unsafe { &*(&spl_associated_token_account::id() as *const Pubkey as *const [u8; 32]) },
189    )
190    .0,
191);
192
193pub const MIRACLE_ESCROW_ADDRESS: Pubkey = Pubkey::new_from_array(
194    ed25519::derive_program_address(
195        &[
196            ESCROW,
197            unsafe { &*(&MIRACLE_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
198            unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
199        ],
200        &PROGRAM_ID,
201    )
202    .0,
203);
204pub const MIRACLE_ESCROW_BUMP: u8 = ed25519::derive_program_address(
205    &[
206        ESCROW,
207        unsafe { &*(&MIRACLE_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
208        unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
209    ],
210    &PROGRAM_ID,
211)
212.1;
213pub const MIRACLE_ESCROW_TOKENS_ADDRESS: Pubkey = Pubkey::new_from_array(
214    ed25519::derive_program_address(
215        &[
216            unsafe { &*(&MIRACLE_ESCROW_ADDRESS as *const Pubkey as *const [u8; 32]) },
217            unsafe { &*(&spl_token::id() as *const Pubkey as *const [u8; 32]) },
218            unsafe { &*(&MIRACLE_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
219        ],
220        unsafe { &*(&spl_associated_token_account::id() as *const Pubkey as *const [u8; 32]) },
221    )
222    .0,
223);
224
225pub const USDC_ESCROW_ADDRESS: Pubkey = Pubkey::new_from_array(
226    ed25519::derive_program_address(
227        &[
228            ESCROW,
229            unsafe { &*(&USDC_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
230            unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
231        ],
232        &PROGRAM_ID,
233    )
234    .0,
235);
236pub const USDC_ESCROW_BUMP: u8 = ed25519::derive_program_address(
237    &[
238        ESCROW,
239        unsafe { &*(&USDC_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
240        unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
241    ],
242    &PROGRAM_ID,
243)
244.1;
245pub const USDC_ESCROW_TOKENS_ADDRESS: Pubkey = Pubkey::new_from_array(
246    ed25519::derive_program_address(
247        &[
248            unsafe { &*(&USDC_ESCROW_ADDRESS as *const Pubkey as *const [u8; 32]) },
249            unsafe { &*(&spl_token::id() as *const Pubkey as *const [u8; 32]) },
250            unsafe { &*(&USDC_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
251        ],
252        unsafe { &*(&spl_associated_token_account::id() as *const Pubkey as *const [u8; 32]) },
253    )
254    .0,
255);
256
257pub const USDT_ESCROW_ADDRESS: Pubkey = Pubkey::new_from_array(
258    ed25519::derive_program_address(
259        &[
260            ESCROW,
261            unsafe { &*(&USDT_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
262            unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
263        ],
264        &PROGRAM_ID,
265    )
266    .0,
267);
268pub const USDT_ESCROW_BUMP: u8 = ed25519::derive_program_address(
269    &[
270        ESCROW,
271        unsafe { &*(&USDT_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
272        unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
273    ],
274    &PROGRAM_ID,
275)
276.1;
277pub const USDT_ESCROW_TOKENS_ADDRESS: Pubkey = Pubkey::new_from_array(
278    ed25519::derive_program_address(
279        &[
280            unsafe { &*(&USDT_ESCROW_ADDRESS as *const Pubkey as *const [u8; 32]) },
281            unsafe { &*(&spl_token::id() as *const Pubkey as *const [u8; 32]) },
282            unsafe { &*(&USDT_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
283        ],
284        unsafe { &*(&spl_associated_token_account::id() as *const Pubkey as *const [u8; 32]) },
285    )
286    .0,
287);
288
289pub const WSOL_ESCROW_ADDRESS: Pubkey = Pubkey::new_from_array(
290    ed25519::derive_program_address(
291        &[
292            ESCROW,
293            unsafe { &*(&WSOL_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
294            unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
295        ],
296        &PROGRAM_ID,
297    )
298    .0,
299);
300pub const WSOL_ESCROW_BUMP: u8 = ed25519::derive_program_address(
301    &[
302        ESCROW,
303        unsafe { &*(&WSOL_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
304        unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
305    ],
306    &PROGRAM_ID,
307)
308.1;
309pub const WSOL_ESCROW_TOKENS_ADDRESS: Pubkey = Pubkey::new_from_array(
310    ed25519::derive_program_address(
311        &[
312            unsafe { &*(&WSOL_ESCROW_ADDRESS as *const Pubkey as *const [u8; 32]) },
313            unsafe { &*(&spl_token::id() as *const Pubkey as *const [u8; 32]) },
314            unsafe { &*(&WSOL_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
315        ],
316        unsafe { &*(&spl_associated_token_account::id() as *const Pubkey as *const [u8; 32]) },
317    )
318    .0,
319);
320pub const TESTCOIN_ESCROW_ADDRESS: Pubkey = Pubkey::new_from_array(
321    ed25519::derive_program_address(
322        &[
323            ESCROW,
324            unsafe { &*(&TESTCOIN_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
325            unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
326        ],
327        &PROGRAM_ID,
328    )
329    .0,
330);
331pub const TESTCOIN_ESCROW_BUMP: u8 = ed25519::derive_program_address(
332    &[
333        ESCROW,
334        unsafe { &*(&TESTCOIN_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
335        unsafe { &*(&BANK_ADDRESS as *const Pubkey as *const [u8; 32]) },
336    ],
337    &PROGRAM_ID,
338)
339.1;
340pub const TESTCOIN_ESCROW_TOKENS_ADDRESS: Pubkey = Pubkey::new_from_array(
341    ed25519::derive_program_address(
342        &[
343            unsafe { &*(&TESTCOIN_ESCROW_ADDRESS as *const Pubkey as *const [u8; 32]) },
344            unsafe { &*(&spl_token::id() as *const Pubkey as *const [u8; 32]) },
345            unsafe { &*(&TESTCOIN_MINT_ADDRESS as *const Pubkey as *const [u8; 32]) },
346        ],
347        unsafe { &*(&spl_associated_token_account::id() as *const Pubkey as *const [u8; 32]) },
348    )
349    .0,
350);