پرش به مطلب اصلی

مرجع قراردادها

این صفحه مرجع مهندسی اجزای آن‌چین پشته غیرامانی است. آدرس‌ها و گزارش‌های حسابرسی با انتشار هر فاز، برای هر زنجیره در ادامه منتشر می‌شوند.

قواعد آدرس (EVM)​

هر چهار قرارداد EVM یک deployer مشترک دارند (یک deployer قطعی CREATE2، مثلاً 0x4e59b44847b379578588920cA78FbF26c0B4956C) و برای هر نسخه هش init code یکسانی دارند، بنابراین آدرس factory و هاب روی همه زنجیره‌های EVM یکسان است. این کار کد کلاینت و مستندات را ساده می‌کند.

زنجیرهchainIdPaymentLinkFactorySubscriptionHubFeeSplitter
Base8453هنگام استقرار منتشر می‌شودهنگام استقرار منتشر می‌شودهنگام استقرار منتشر می‌شود
Ethereum1یکسانیکسانیکسان
Arbitrum One42161یکسانیکسانیکسان
Optimism10یکسانیکسانیکسان
Polygon PoS137یکسانیکسانیکسان

آدرس‌های PaymentLinkReceiver برای هر لینک جداست: factory.computeAddress(keccak256(linkId)).

EVM: PaymentLinkFactory​

توابع​

  • computeAddress(bytes32 linkId) external view returns (address): آدرس قطعی CREATE2. پیش از هر استقراری قابل فراخوانی است.
  • deployAndPay(bytes32 linkId, Split calldata split, address token, uint256 amount) external payable: کلون را در اولین پرداخت مستقر می‌کند و وجوه را منتقل می‌کند.
  • isDeployed(bytes32 linkId) external view returns (bool).
  • setSplit(bytes32 linkId, Split calldata split) external: فقط پیش از اولین پرداخت قابل فراخوانی است؛ تقسیم تغییرناپذیری را که کلون با آن مقداردهی می‌شود تعیین می‌کند.
  • pause() / unpause(): فقط مولتی‌سیگ.

رویدادها​

  • ReceiverDeployed(bytes32 indexed linkId, address receiver)
  • SplitRegistered(bytes32 indexed linkId, Split split)

ساختار Split​

struct Split {
address merchant;
address platform;
address referral;
address bridgeFee;
uint16 platformBps;
uint16 referralBps;
uint16 bridgeFeeBps;
}

مجموع فیلدهای bps باید < 10000 باشد. باقی‌مانده به پذیرنده می‌رسد.

EVM: PaymentLinkReceiver (کلون حداقلی)​

توابع​

  • pay(address token, uint256 amount) external payable: نقطه ورود اصلی. token == address(0) یعنی ارز بومی.
  • refund(bytes32 txId, address to, uint256 amount) external: محدود به EOA keeper یا مولتی‌سیگ استقرار.
  • split() external view returns (Split memory).

رویدادها​

  • Paid(bytes32 indexed linkId, address indexed payer, address indexed token, uint256 amount, bytes32 txId)
  • Refunded(bytes32 indexed linkId, bytes32 indexed txId, address to, uint256 amount)

Revertها​

  • InvalidToken، InvalidAmount، SplitFailed، AlreadyRefunded.

EVM: FeeSplitter​

توابع​

  • split(Split calldata s, address token, uint256 amount) external payable: فراخوانی داخلی از PaymentLinkReceiver و SubscriptionHub. معمولاً مستقیم فراخوانی نمی‌شود.

رویدادها​

  • SplitExecuted(bytes32 indexed txId, address merchant, uint256 merchantAmount, address platform, uint256 platformAmount, address referral, uint256 referralAmount, address bridgeFee, uint256 bridgeFeeAmount)

EVM: SubscriptionHub​

توابع​

  • createSubscription(bytes32 id, address payer, IERC20 token, uint256 amount, uint64 interval, uint256 cap, Split calldata split) external: اشتراک را آن‌چین ثبت می‌کند.
  • charge(bytes32 id) external: عمومی و بدون نیاز به مجوز؛ زمان‌بندی، سقف، allowance و موجودی را اعمال می‌کند.
  • charge(bytes32[] ids) external: نسخه دسته‌ای؛ هر id مستقل اعتبارسنجی می‌شود.
  • cancel(bytes32 id) external: پرداخت‌کننده می‌تواند فراخوانی کند.
  • subscription(bytes32 id) external view returns (Subscription memory).
  • isDue(bytes32 id) external view returns (bool): تابع کمکی برای keeperها.

رویدادها​

  • SubscriptionCreated(bytes32 indexed id, address indexed payer, IERC20 token, uint256 amount, uint64 interval, uint256 cap)
  • Charged(bytes32 indexed id, uint256 amount, uint64 nextChargeAt)
  • ChargeSkipped(bytes32 indexed id, bytes32 reason): دلایل: NotDue، InsufficientAllowance، InsufficientBalance، AlreadyChargedThisPeriod، CapExceeded، Paused.
  • Canceled(bytes32 indexed id)

ناورداهایی که charge اعمال می‌کند​

  • block.timestamp >= subscription.nextChargeAt
  • block.timestamp > subscription.lastChargedAt (یکنوا)
  • subscription.amountCharged + subscription.amount <= subscription.cap
  • token.allowance(subscription.payer, address(this)) >= subscription.amount
  • token.balanceOf(subscription.payer) >= subscription.amount

نمونه جریان پرداخت‌کننده​

// 1. Payer signs an allowance to the hub
await usdc.approve(subscriptionHub.address, cap)

// 2. Merchant (via OrcaRail) creates the subscription on-chain
await subscriptionHub.createSubscription(
id,
payer,
usdc,
amount,
interval,
cap,
split
)

// 3. Anyone calls charge when due
await subscriptionHub.charge(id)

حساب‌ها​

#[account]
pub struct PaymentLink {
pub link_id: [u8; 32],
pub expected_mint: Pubkey,
pub expected_amount: u64,
pub split: Split,
pub created_at: i64,
pub status: PaymentStatus,
}

seedهای PDA: [b"pl", link_id].

دستورها​

  • initialize(link_id, expected_mint, expected_amount, split): مقداردهی تنبل در اولین استفاده.
  • pay(link_id, amount): با CPI از ATA پرداخت‌کننده به ATA مربوط به PDA منتقل می‌کند، سپس با CPI تقسیم می‌کند.
  • refund(link_id): محدود به مولتی‌سیگ.

رویدادها​

  • PaymentReceived { link_id, payer, amount }
  • PaymentRefunded { link_id, to, amount }

سولانا: برنامه subscription​

حساب‌ها​

#[account]
pub struct Subscription {
pub id: [u8; 32],
pub payer: Pubkey,
pub mint: Pubkey,
pub amount: u64,
pub interval: i64,
pub cap: u64,
pub amount_charged: u64,
pub next_charge_at: i64,
pub last_charged_at: i64,
pub split: Split,
}

دستورها​

  • create(id, payer, mint, amount, interval, cap, split): اشتراک را ثبت می‌کند.
  • charge(id): عمومی؛ ساعت، سقف و اختیار delegate را بررسی می‌کند و سپس به‌عنوان delegate با CPI ‏transfer_checked را اجرا می‌کند.
  • cancel(id): فقط پرداخت‌کننده.

رویدادها (از طریق لاگ‌های برنامه)​

  • SubscriptionCreated، Charged { amount, next_charge_at }، ChargeSkipped { reason }، Canceled.

نمونه جریان پرداخت‌کننده​

// 1. Payer approves program PDA as delegate on their USDC ATA
await token.approve(payerUsdcAta, programPda, capAmount)

// 2. create() registers the subscription PDA
// 3. charge() can be called by anyone once due

الگوی descriptor​

wsh(multi(2, <merchant_pubkey>, <platform_pubkey>))

معادل taproot (نسخه ۲، پس از بلوغ ابزارهای MuSig2):

tr(<NUMS>, multi_a(2, <merchant_pubkey>, <platform_pubkey>))

اشتقاق​

  • کلید پذیرنده: از xpub ثبت‌شده پذیرنده هنگام ثبت‌نام مشتق می‌شود، یک index برای هر لینک پرداخت.
  • کلید پلتفرم: از xpub مربوط به HSM پلتفرم مشتق می‌شود، یک index برای هر لینک پرداخت.

PSBT بازپرداخت​

در زمان واریز، یک PSBT امضانشده ساخته می‌شود که مبلغ واریز منهای کارمزد را به پرداخت‌کننده برمی‌گرداند. هر دو امضاکننده بلافاصله آن را امضا می‌کنند؛ نتیجه رمزنگاری‌شده ذخیره می‌شود و هر زمان بدون امضای دیگری قابل انتشار است.

گزارش‌های حسابرسی​

با تکمیل هر حسابرسی اینجا منتشر می‌شوند. هر مورد شامل: شرکت حسابرسی، محدوده، commit، تاریخ، لینک گزارش و commit رفع اشکال.

(گزارش‌ها با انتشار فازها اضافه می‌شوند.)

همچنین ببینید​