IPrivacy.transferWithAuthorization

transferWithAuthorization(
  PrivacyTransferRequest request,
  PrivacyActionAuthorization authorization
) external returns (bool success)

EIP-712 PrivacyActionAuthorization에 서명한 effectiveSender를 대신하여 셸디드 transfer를 실행합니다. 릴레이어가 msg.sender이며, authorization이 nonce가 소비되고 PCL 규칙이 적용되는 발신자를 지정합니다. 실패는 이제 IPrivacy의 타입 지정 커스텀 오류(authorization 검사, 요청 만료, nullifier/커밋먼트 충돌, 배치 한도) 또는 IPrecompile의 상속 오류(InvalidNumberOfArgs, RequesterIsNotMsgSender 등)로 revert됩니다. PCL 정책 실패는 여전히 IPcl의 PCL ReasonCode로 노출됩니다.

파라미터

이름 타입 필수 설명
request PrivacyTransferRequest 셸디드 transfer 페이로드입니다. expiresAtUnix는 현재 블록 시간보다 반드시 커야 합니다. 만료되었거나 0이면 PrivacyRequestExpired(expiresAtUnix)로 revert됩니다.
authorization PrivacyActionAuthorization effective sender가 EIP-712로 서명한 권한입니다. effectiveSender, executor, nonce, deadline이 모두 설정되어야 하며, 누락 시 PrivacyInvalidAuthorizationField(field)로 revert됩니다. executormsg.sender와 같아야 하며, 다르면 RequesterIsNotMsgSender로 revert됩니다. 서명은 effectiveSender로 복원되어야 하며, 다르면 PrivacyAuthorizationSignerMismatch(expected, got)로 revert됩니다. 정확한 typeHash 원본은 privacy-authorization-eip712-domain을 참고합니다.

반환값

타입: bool

성공 시 true를 반환합니다. 실패는 false 반환이 아니라 타입 지정 커스텀 오류로 revert됩니다.

에러

코드 이름 설명
PrivacyNonPayable PrivacyNonPayable msg.value가 0이 아닐 때 revert됩니다. payable은 deposit뿐입니다. PrivacyNonPayable(string methodName)으로 인코딩됩니다.
PrivacyRequestExpired PrivacyRequestExpired request.expiresAtUnix가 0이거나 이미 지났을 때 revert됩니다. 페이로드에는 문제가 된 unix 타임스탬프가 담깁니다.
PrivacyInvalidAuthorizationField PrivacyInvalidAuthorizationField 필수 authorization 필드가 누락되었거나 유효하지 않을 때 revert됩니다. 페이로드는 필드 이름("effectiveSender", "executor", "nonce", "deadline")입니다.
PrivacyAuthorizationExpired PrivacyAuthorizationExpired authorization의 deadline이 현재 블록 시간을 기준으로 지났을 때 revert됩니다.
PrivacyAuthorizationNonceUsed PrivacyAuthorizationNonceUsed 해당 effective sender에 대해 nonce가 이미 소비되었을 때 revert됩니다. 페이로드는 (sender, nonce)입니다.
PrivacyAuthorizationSignerMismatch PrivacyAuthorizationSignerMismatch 복원된 서명자가 effectiveSender와 다를 때 revert됩니다. 페이로드는 (expected, got)입니다.
PrivacyAuthorizationRejected PrivacyAuthorizationRejected ERC-1271 또는 EIP-7702 authorization이 검증기에서 거절되었을 때(잘못된 코드 형태, 검증기 revert, 지원되지 않는 authorization kind) revert됩니다. 페이로드는 authorization kind입니다.
PrivacyInvalidAuthorizationMagic PrivacyInvalidAuthorizationMagic ERC-1271 스마트 계정이 0x1626ba7e 매직이 아닌 바이트를 반환했을 때 revert됩니다. 페이로드는 반환된 매직 바이트입니다.
PrivacyNullifierAlreadySpent PrivacyNullifierAlreadySpent 요청의 nullifier가 이미 온체인에 기록되어 있을 때 revert됩니다.
PrivacyCommitmentAlreadyExists PrivacyCommitmentAlreadyExists 요청의 새 커밋먼트가 이미 Merkle 트리에 존재할 때 revert됩니다.
PrivacyMerkleCapacityExceeded PrivacyMerkleCapacityExceeded 요청의 새 커밋먼트들을 추가하면 Merkle 트리 용량을 초과할 때 revert됩니다.
PrivacyTxLimitExceeded PrivacyTxLimitExceeded 단일 EVM 실행 내에서 전역 stateful-privacy 호출 한도를 트랜잭션이 이미 초과했을 때 revert됩니다.
PrivacySenderTxLimitExceeded PrivacySenderTxLimitExceeded effective sender별 stateful-privacy 호출 한도를 트랜잭션이 이미 초과했을 때 revert됩니다.
RequesterIsNotMsgSender RequesterIsNotMsgSender IPrecompile에서 상속됩니다. authorization.executormsg.sender와 다를 때 revert됩니다. 페이로드는 (msgSender, requester)입니다.
InvalidNumberOfArgs InvalidNumberOfArgs IPrecompile에서 상속됩니다. ABI 인코딩된 호출이 정확히 두 개의 인자를 담고 있지 않을 때 revert됩니다.
UnknownMethod UnknownMethod IPrecompile에서 상속됩니다. ABI selector가 프리컴파일의 어떤 함수와도 일치하지 않을 때 revert됩니다. 보통 ABI가 오래된 상황을 의미합니다.

예제

릴레이어가 인증된 transfer 제출

릴레이어가 msg.sender가 되며, PCL은 authorization.effectiveSender를 기준으로 규칙을 평가합니다. 검사에 실패하면 호출 전체가 해당 타입 지정 오류로 revert됩니다.

import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { privacyAbi } from "@maroo-chain/contracts/abi/IPrivacy";

const PRIVACY = "0x100000000000000000000000000000000000000b" as const;

const relayer = createWalletClient({
  account: privateKeyToAccount(process.env.RELAYER_KEY as `0x${string}`),
  transport: http("https://rpc-testnet.maroo.io"),
});

// `request` and `authorization` are built off-chain; the effective sender
// signs the EIP-712 typeHash preimage (see privacy-authorization-eip712-domain).
// authorization.executor MUST equal the relayer address.
await relayer.writeContract({
  address: PRIVACY,
  abi: privacyAbi,
  functionName: "transferWithAuthorization",
  args: [request, authorization],
});

authorization / 만료 오류 디코드

decoded.errorName으로 분기합니다. 각 타입 지정 오류의 인자 튜플은 안정적이며 (address, bigint) 같은 타입 값으로 디코드되어 UX에 바로 사용할 수 있습니다.

import { decodeErrorResult } from "viem";
import { privacyAbi } from "@maroo-chain/contracts/abi/IPrivacy";

try {
  await relayer.writeContract({
    address: PRIVACY,
    abi: privacyAbi,
    functionName: "transferWithAuthorization",
    args: [request, authorization],
  });
} catch (err: any) {
  if (!err?.data) throw err;
  const decoded = decodeErrorResult({ abi: privacyAbi, data: err.data });
  switch (decoded.errorName) {
    case "PrivacyAuthorizationNonceUsed": {
      const [sender, nonce] = decoded.args as [`0x${string}`, bigint];
      console.warn(`nonce ${nonce} already consumed for ${sender}`);
      break;
    }
    case "PrivacyRequestExpired": {
      const [expiresAtUnix] = decoded.args as [bigint];
      console.warn(`request expired at ${expiresAtUnix}`);
      break;
    }
    case "PrivacyAuthorizationSignerMismatch": {
      const [expected, got] = decoded.args as [`0x${string}`, `0x${string}`];
      console.warn(`bad signature: expected ${expected}, got ${got}`);
      break;
    }
    default:
      throw err;
  }
}
ESC
검색어를 입력하세요