/** * RWATransferAdapterClient — permissioned RWA → USDC.e redemption. * Contract: aerenew/contracts/contracts/lending/RWATransferAdapter.sol */ export interface RpcProvider { request(args: { method: string; params: unknown[] }): Promise; } const pad32 = (h: string) => h.toLowerCase().replace(/^0x/, '').padStart(64, '0'); const encUint = (n: bigint) => pad32(n.toString(16)); const encAddr = (a: string) => pad32(a.replace(/^0x/, '')); async function ethCall(p: RpcProvider, to: string, data: string): Promise { return await p.request({ method: 'eth_call', params: [{ to, data }, 'latest'] }) as string; } async function ethSend(p: RpcProvider, from: string, to: string, data: string): Promise { return await p.request({ method: 'eth_sendTransaction', params: [{ from, to, data, value: '0x0' }] }) as string; } const SEL = { PAYOUT_TOKEN: '0x935ca8e6', // PAYOUT_TOKEN() ORACLE: '0x7dc0d1d0', // ORACLE() FOUNDATION: '0x4d09f93e', // FOUNDATION() configs: '0x1d12be96', // configs(address) states: '0xb95da3ec', // states(address) periodRemaining: '0x3aff0d34', // periodRemaining(address) payoutLiquidity: '0x8b8a55be', // payoutLiquidity() redeem: '0x1e9a6950', // redeem(address,uint256) } as const; export class RWATransferAdapterClient { constructor(public readonly provider: RpcProvider, public readonly address: string) {} async getPayoutToken(): Promise { return '0x' + (await ethCall(this.provider, this.address, SEL.PAYOUT_TOKEN)).slice(-40); } async getFoundation(): Promise { return '0x' + (await ethCall(this.provider, this.address, SEL.FOUNDATION)).slice(-40); } async periodRemaining(asset: string): Promise { return BigInt(await ethCall(this.provider, this.address, SEL.periodRemaining + encAddr(asset))); } async payoutLiquidity(): Promise { return BigInt(await ethCall(this.provider, this.address, SEL.payoutLiquidity)); } /** Permissionless redeem. Caller must approve `asset` for `rwaAmount` on this contract first. */ async redeem(from: string, asset: string, rwaAmount: bigint): Promise { return ethSend(this.provider, from, this.address, SEL.redeem + encAddr(asset) + encUint(rwaAmount)); } }