Skip to content
This repository was archived by the owner on Apr 19, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clean-jsdoc-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@abstract-foundation/mpp": patch
---

Remove AI-generated separator comments and add JSDoc to all undocumented exports
4 changes: 0 additions & 4 deletions packages/mpp/src/client/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import { Method, z } from 'mppx';
import { parseUnits } from 'viem';

// ── Charge ────────────────────────────────────────────────────────────────

/**
* Abstract charge intent — one-time ERC-3009 transfer authorization.
*
Expand Down Expand Up @@ -47,8 +45,6 @@ export const abstractChargeMethods = Method.from({
},
});

// ── Session ───────────────────────────────────────────────────────────────

/**
* Abstract session intent — payment channels backed by AbstractStreamChannel.
*/
Expand Down
10 changes: 4 additions & 6 deletions packages/mpp/src/client/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ const ERC20_ABI = [
] as const;

export interface AbstractSessionClientOptions {
/** Viem account for signing vouchers and channel transactions. */
account: Account;
/** Optional custom RPC URL override. */
rpcUrl?: string;
/**
* Default deposit amount as human-readable string (e.g. "10" for 10 USDC.e).
Expand All @@ -68,11 +70,13 @@ export interface AbstractSessionClientOptions {
deposit?: string;
/** Override escrow contract (falls back to challenge.request.methodDetails.escrowContract). */
escrowContract?: Address;
/** Override the wallet client factory (advanced). */
getClient?: (
chainId: number,
) =>
| WalletClient<Transport, ChainEIP712, Account>
| Promise<WalletClient<Transport, ChainEIP712, Account>>;
/** Override the public client factory (advanced). */
getPublicClient?: (
chainId: number,
) =>
Expand Down Expand Up @@ -196,7 +200,6 @@ export function abstractSession(options: AbstractSessionClientOptions) {
const key = channelKey(recipient, currency, escrowContract);
let entry = channels.get(key);

// ── Open a new channel ────────────────────────────────────────────────
if (!entry) {
const suggestedDepositRaw = req.suggestedDeposit as string | undefined;
const decimals = (req.decimals as number | undefined) ?? 6;
Expand All @@ -213,7 +216,6 @@ export function abstractSession(options: AbstractSessionClientOptions) {

const salt = randomBytes32();

// Ensure allowance
const currentAllowance = await publicClient.readContract({
address: currency,
abi: ERC20_ABI,
Expand All @@ -232,7 +234,6 @@ export function abstractSession(options: AbstractSessionClientOptions) {
await publicClient.waitForTransactionReceipt({ hash: approveTx });
}

// Open channel
const openTx = await walletClient.writeContract({
account,
address: escrowContract,
Expand All @@ -248,7 +249,6 @@ export function abstractSession(options: AbstractSessionClientOptions) {
});
await publicClient.waitForTransactionReceipt({ hash: openTx });

// Compute channelId
const channelId = (await publicClient.readContract({
address: escrowContract,
abi: ABSTRACT_STREAM_CHANNEL_ABI,
Expand All @@ -275,7 +275,6 @@ export function abstractSession(options: AbstractSessionClientOptions) {
await options.onChannelOpened(channelId);
}

// Sign opening voucher
entry.cumulativeAmount += amount;
const voucherSig = await signVoucherSig(
chainId,
Expand All @@ -300,7 +299,6 @@ export function abstractSession(options: AbstractSessionClientOptions) {
});
}

// ── Voucher for existing channel ──────────────────────────────────────
entry.cumulativeAmount += amount;
const sig = await signVoucherSig(
chainId,
Expand Down
27 changes: 10 additions & 17 deletions packages/mpp/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,18 @@ export const USDC_E_MAINNET =
/** USDC.e decimals */
export const USDC_E_DECIMALS = 6;

// ── AbstractStreamChannel deployments ──────────────────────────────────────

/** AbstractStreamChannel escrow contract on Abstract Testnet. */
export const ABSTRACT_STREAM_CHANNEL_TESTNET =
'0x29635C384f451a72ED2e2a312BCeb8b0bDC0923c' as const;
/** AbstractStreamChannel escrow contract on Abstract Mainnet. */
export const ABSTRACT_STREAM_CHANNEL_MAINNET =
'0x29635C384f451a72ED2e2a312BCeb8b0bDC0923c' as const;

// ── ERC-3009 typehash ──────────────────────────────────────────────────────

/** Keccak-256 typehash for ERC-3009 `TransferWithAuthorization`. */
export const TRANSFER_WITH_AUTHORIZATION_TYPEHASH =
'0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267' as const;

// ── ERC-3009 ABI fragments ─────────────────────────────────────────────────

/** ABI fragments for ERC-3009 `transferWithAuthorization` (v/r/s signature variant). */
export const ERC3009_ABI = [
{
name: 'transferWithAuthorization',
Expand Down Expand Up @@ -73,6 +69,7 @@ export const ERC3009_ABI = [
},
] as const;

/** ABI fragment for ERC-3009 `transferWithAuthorization` (bytes signature variant). */
export const ERC3009_BYTES_SIGNATURE_ABI = [
{
name: 'transferWithAuthorization',
Expand All @@ -91,8 +88,7 @@ export const ERC3009_BYTES_SIGNATURE_ABI = [
},
] as const;

// ── AbstractStreamChannel ABI ──────────────────────────────────────────────

/** ABI for the AbstractStreamChannel escrow contract. */
export const ABSTRACT_STREAM_CHANNEL_ABI = [
{
name: 'open',
Expand Down Expand Up @@ -219,7 +215,6 @@ export const ABSTRACT_STREAM_CHANNEL_ABI = [
inputs: [],
outputs: [{ name: '', type: 'uint64' }],
},
// Events
{
name: 'ChannelOpened',
type: 'event',
Expand Down Expand Up @@ -269,20 +264,20 @@ export const ABSTRACT_STREAM_CHANNEL_ABI = [
},
] as const;

// ── EIP-712 voucher domain (matches AbstractStreamChannel) ─────────────────

/** EIP-712 domain name for session voucher signatures. */
export const VOUCHER_DOMAIN_NAME = 'Abstract Stream Channel';
/** EIP-712 domain version for session voucher signatures. */
export const VOUCHER_DOMAIN_VERSION = '1';

/** EIP-712 type definition for `Voucher` typed data. */
export const VOUCHER_TYPES = {
Voucher: [
{ name: 'channelId', type: 'bytes32' },
{ name: 'cumulativeAmount', type: 'uint128' },
],
} as const;

// ── EIP-712 ERC-3009 transfer types ────────────────────────────────────────

/** EIP-712 type definition for `TransferWithAuthorization` typed data. */
export const TRANSFER_WITH_AUTHORIZATION_TYPES = {
TransferWithAuthorization: [
{ name: 'from', type: 'address' },
Expand All @@ -294,15 +289,13 @@ export const TRANSFER_WITH_AUTHORIZATION_TYPES = {
],
} as const;

// ── Default currency map by chainId ───────────────────────────────────────

/** USDC.e address by Abstract chainId (testnet/mainnet). */
export const DEFAULT_CURRENCY = {
[abstractTestnet.id]: USDC_E_TESTNET,
[abstract.id]: USDC_E_MAINNET,
};

// ── Default escrow contract map by chainId ───────────────────────────────

/** AbstractStreamChannel address by Abstract chainId (testnet/mainnet). */
export const DEFAULT_ESCROW = {
[abstractTestnet.id]: ABSTRACT_STREAM_CHANNEL_TESTNET,
[abstract.id]: ABSTRACT_STREAM_CHANNEL_MAINNET,
Expand Down
4 changes: 4 additions & 0 deletions packages/mpp/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { bytesToHex } from 'viem';
import { abstract, abstractTestnet } from 'viem/chains';
import type { ChainEIP712 } from 'viem/zksync';

/** Maximum value for a `uint128` (2^128 - 1). */
export const UINT128_MAX = 2n ** 128n - 1n;

/** Resolves an Abstract chainId to its viem Chain definition. */
export function resolveChain(chainId: number): ChainEIP712 {
if (chainId === abstract.id) return abstract;
if (chainId === abstractTestnet.id) return abstractTestnet;
Expand All @@ -13,6 +15,7 @@ export function resolveChain(chainId: number): ChainEIP712 {
);
}

/** Throws if amount is outside uint128 range. */
export function assertUint128(amount: bigint): void {
if (amount < 0n || amount > UINT128_MAX) {
throw new Errors.VerificationFailedError({
Expand All @@ -21,6 +24,7 @@ export function assertUint128(amount: bigint): void {
}
}

/** Generates a cryptographically random 32-byte hex string. */
export function randomBytes32(): `0x${string}` {
const bytes = new Uint8Array(32);
globalThis.crypto.getRandomValues(bytes);
Expand Down
2 changes: 0 additions & 2 deletions packages/mpp/src/server/charge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ export function charge(params: AbstractChargeServerOptions) {
const validBefore = payload.validBefore as string;
const from = payload.from as Address;

// Verify ERC-3009 signature
const domain = await getErc3009Domain(
publicClient,
currencyAddr,
Expand All @@ -236,7 +235,6 @@ export function charge(params: AbstractChargeServerOptions) {
throw new Error('ERC-3009 signature verification failed');
}

// Check nonce not already used
const used = (await publicClient.readContract({
address: currencyAddr,
abi: ERC3009_ABI,
Expand Down
14 changes: 0 additions & 14 deletions packages/mpp/src/server/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ import {
} from '../constants.js';
import { assertUint128, resolveChain } from '../internal.js';

// ── Types ─────────────────────────────────────────────────────────────────

interface VoucherRecord {
channelId: Hex;
cumulativeAmount: bigint;
Expand All @@ -63,8 +61,6 @@ interface ChannelState {
createdAt: string;
}

// ── ChannelStore ──────────────────────────────────────────────────────────

interface ChannelStore {
getChannel(channelId: Hex): Promise<ChannelState | null>;
updateChannel(
Expand Down Expand Up @@ -112,8 +108,6 @@ function channelStoreFromStore(store: Store.Store): ChannelStore {
};
}

// ── Options ────────────────────────────────────────────────────────────────

export interface AbstractSessionServerOptions {
/** Server account (broadcasts close/settle transactions). */
account: Account;
Expand Down Expand Up @@ -145,8 +139,6 @@ export interface AbstractSessionServerOptions {
store?: Store.Store;
}

// ── Helpers ────────────────────────────────────────────────────────────────

async function verifyVoucherSig(
publicClient: PublicClient,
escrowContract: Address,
Expand Down Expand Up @@ -198,8 +190,6 @@ function makeSessionReceipt(params: {
};
}

// ── Main export ────────────────────────────────────────────────────────────

/**
* Creates a server-side Abstract session handler.
*
Expand Down Expand Up @@ -310,7 +300,6 @@ export function session(params: AbstractSessionServerOptions) {
const action = payload.action as string;

switch (action) {
// ── OPEN ────────────────────────────────────────────────────────────
case 'open': {
const channelId = payload.channelId as Hex;
const cumulativeAmount = BigInt(payload.cumulativeAmount as string);
Expand Down Expand Up @@ -411,7 +400,6 @@ export function session(params: AbstractSessionServerOptions) {
});
}

// ── TOPUP ───────────────────────────────────────────────────────────
case 'topUp': {
const channelId = payload.channelId as Hex;
const txHash = payload.txHash as Hex;
Expand Down Expand Up @@ -456,7 +444,6 @@ export function session(params: AbstractSessionServerOptions) {
});
}

// ── VOUCHER ─────────────────────────────────────────────────────────
case 'voucher': {
const channelId = payload.channelId as Hex;
const cumulativeAmount = BigInt(payload.cumulativeAmount as string);
Expand Down Expand Up @@ -536,7 +523,6 @@ export function session(params: AbstractSessionServerOptions) {
});
}

// ── CLOSE ───────────────────────────────────────────────────────────
case 'close': {
const channelId = payload.channelId as Hex;
const cumulativeAmount = BigInt(payload.cumulativeAmount as string);
Expand Down
Loading