@megaeth-labs/wallet-intent
v0.1.5
Published
Shared V0.6 Intent primitives for MegaETH wallet, merchant, and SDKs.
Downloads
2,058
Maintainers
Keywords
Readme
@megaeth-labs/wallet-intent
Shared primitives for building, signing, and submitting the MegaETH V0.6
Intent payload that the relay's wallet_sendCalls consumes.
Used by:
@megaeth-labs/wallet— callssendCallsdirectly for non-sponsored sends, and points it at a merchant URL for sponsored sends.@megaeth-labs/wallet-merchant— the sponsor backend receives the unsigned intent and signingkeyTypeover HTTP, setspayer = merchant address, fillspaymentSignature, re-runsprepareIntentwith thatkeyType, and returns the re-derived{ intent, digest }for the wallet to sign.
The package exposes a tiny surface: a single high-level sendCalls action
that wraps orchestrator lookups, nonce reads, payment-rate fetches, the
optional merchant round-trip, signing, and the JSON-RPC envelope; a sibling
upgradeAccount action that builds the EIP-7702 + multichain preCall
envelope; signMessage / signTypedData / verifyMessage for personal-sign
and typed-data flows (with ERC-8010 wrapping when the EOA is not yet
delegated); and the low-level prepareIntent / IntentV06 /
getPaymentPerGas / pickPaymentPerGasFor / ESTIMATED_GAS_BUDGET
building blocks for callers that need them.
paymentPerGas is quoted by the relay as a 1e18 fixed-point scalar —
the orchestrator computes the actual fee as
gasUsed × paymentPerGas / 10^18, so multiplying gas by the raw
paymentPerGas overshoots by 1e18. Divide by
PAYMENT_PER_GAS_FIXED_POINT_SCALAR to land at the correct fee-token
base-unit amount, regardless of the token's decimals.
Install
pnpm add @megaeth-labs/wallet-intentDuring local development the consumer repos use a file: dependency:
{
"dependencies": {
"@megaeth-labs/wallet-intent": "*"
}
}Run pnpm build in this repo first so dist/ exists.
Surface
import {
sendCalls,
prepareIntent,
getPaymentPerGas,
pickPaymentPerGasFor,
ESTIMATED_GAS_BUDGET,
PAYMENT_PER_GAS_FIXED_POINT_SCALAR,
PAYMENT_PER_GAS_PRECISION,
upgradeAccount,
getKeys,
signMessage,
signTypedData,
verifyMessage,
type IntentSigningKeyType,
type IntentV06,
type UpgradeAccount,
} from '@megaeth-labs/wallet-intent';Most callers only need sendCalls(client, input). Pass merchantUrl to
route the unsigned intent through a sponsor; omit it for self-paid sends.
When paymentMaxAmount is omitted, sendCalls derives a raw token cap as
ceil((paymentGasBudget ?? ESTIMATED_GAS_BUDGET) × paymentPerGas / 1e18).
Pass an explicit paymentMaxAmount only when you want to override that
computed cap.
When the supplied signing key is the EOA's own root signer (a secp256k1
key whose publicKey matches account.address), sendCalls signs with a
raw 65-byte secp256k1 signature; for sub-keys (other secp256k1, p256,
webauthn) it produces a wrapped signature so the orchestrator can
recover the matching keyHash from keyStorage.
Upgrading an EOA (EIP-7702)
upgradeAccount(client, { account, authorizeKeys }) is pure: it signs the
EIP-7702 authorization for the orchestrator's account proxy and builds the
multichain authorize(key) preCall, then returns
{
account: Address;
status: 'pending';
authorization: SignedAuthorization;
encodedPreCall: Hex;
}Persist that blob yourself (e.g. in localStorage or your wallet's state)
until the chain has consumed it. Pass it back as the authorization field
on sendCalls, signMessage, and signTypedData; each call checks whether
the EOA is already delegated on the target chain and:
- attaches the 7702 authorization +
encodedPreCalltowallet_sendCalls(and surfacesdelegated: truein the receipt) when the EOA is still pending, or - wraps the user signature in an ERC-8010 envelope on
signMessage/signTypedDataso a verifier can lazily runexecutePreCallsbefore checking the signature.
When the chain is already delegated, the supplied authorization is
ignored — callers may pass it unconditionally and advance their own
"delegated chains" tracking off the receipt's delegated flag.
const upgrade = await upgradeAccount(client, {
account,
authorizeKeys: [passkey, sessionKey],
});
await sendCalls(client, { account, calls, authorization: upgrade });