Skip to content

feat(core): add AGW v4 SDK support - #290

Open
mohammeds1992 wants to merge 69 commits into
mainfrom
feat/agw-sdk-v4
Open

mohammeds1992 wants to merge 69 commits into
mainfrom
feat/agw-sdk-v4

Conversation

@mohammeds1992

@mohammeds1992 mohammeds1992 commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds AGW v4 support to @pushchain/core: the client.agentic wallet/rules API, generation-aware contract bindings, owner and agent execution, native and EVM policy support, response/tracking integration, and explicit capability gates for contract or product behavior that is still unavailable.

The implementation is organized by responsibility under packages/core/src/lib/agentic/ (codecs, contracts, execution, management, reads, and response handling). packages/core/AGW.md is the consumer guide. Unit tests, the local real-contract harness, and funded testnet E2Es remain separate validation layers.

Validation

  • 1,982 core unit tests pass; 75 local actual-contract cases pass.
  • Build and lib/spec/local/AGW-E2E typechecks pass; package and public API checks pass.
  • The opt-in agw group contains 39 scenarios. All have passing selected-run live coverage; all remains unchanged and excludes funded AGW cases.
  • Public Solana rule authoring/dispatch remains capability-gated pending the public API decision.

Review note

The plan/agw/ planning and review bundle is temporary and will be removed before merge. The ABI source snapshots required to regenerate the checked-in bindings now live at packages/core/scripts/agw-local/abis/ with a source commit and hash manifest, so code generation no longer depends on the planning bundle.

…ule codecs

Foundation for client.agentic (plan/agw steps 1, 2, 4, 6):

- Typed ABIs generated from the reviewed e704d5b evidence (sha256 in headers)
  and a single contract adapter for execute / executeAsAgent / grant / revoke /
  assertSpent encoding and event decoding.
- Generation registry with on-chain wiring verification. It ships EMPTY: no
  compatible deployment is verified on any network (A07), so every AGW call
  fails with GENERATION_UNSUPPORTED before signing.
- Capability flags that gate target-only features (multi-asset universal
  rules A05, SVM rules, grant ref / setLabel A07, rule history A06,
  compileCard A08) with typed CAPABILITY_UNAVAILABLE errors.
- Pure ID helpers (rulesId, actionId, configId, deriveWallet), native rule
  codec with ABI-layout argument offsets, the single provisional A03 defaults
  table and the A01/A02 policy boundary. Universal rules are validated then
  refused; the historical single-asset terms stay internal and versioned.
- AgenticError / AgenticRevertError (extends PushChainExecutionError) and
  AGW/URP/factory/engine revert decoding, including PolicyCheckReverted.
…responses

Plan/agw steps 3, 5, 7-11 and 13, against the pinned adapter:

- PushChain.initialize(signer, { agenticWallet }): verifies the wallet's
  generation and wiring, then picks the door from the signer's Push identity
  (owner -> execute, agent named in an enabled rule -> executeAsAgent, else
  NOT_OWNER_OR_AGENT). universal.account becomes the wallet; origin, account
  status and gas stay the signer's. reinitialize does not inherit the wallet.
- client.agentic: derive / create / list / wallet(address) handle with info,
  owner, checkpoints, rules.list/get/add/update/revoke. create deploys and
  grants only (no funding), reports partial sequential failures as
  CREATE_PARTIAL with hashes and granted IDs. rules.update is one owner
  execute batch of assertSpent -> revoke -> grant per pair and never falls
  back to sequential sends. setLabel / history / universal rules are
  capability-gated.
- Agentic sends: per-send uncached rule lookup (NO_RULES_FOR_CHAIN /
  DUPLICATE_RULE before signing), FROM_NOT_ALLOWED and
  NOT_ALLOWED_IN_AGENTIC_MODE guards on every transaction-producing entry
  point, native agent arrays refused (A02), signer gas enforced except the
  first-use UEA, and an AGW-originated EVM outbound composer (empty recipient,
  wallet revert recipient, nonzero gas cap, multicall payload, CEA of the
  wallet) that never injects an approval on the agent path.
- Responses keep the signer origin and report the wallet as from on send,
  wait and trackTransaction replay; reads in agentic mode execute through the
  wallet and refund to it. AGENTIC-TX progress events (no 103).
- PushChainExecutionError now keeps its cause so revert data survives, and
  is exported for instanceof checks.
Review-only harness that runs the SDK against the REAL pinned e704d5b
contracts (SmartSession, AgentValidator, UniversalRulesPolicy proxy, AGW
implementation, AGWFactory proxy) on anvil, built from an isolated
`git archive` with submodules fetched at their recorded commits
(scripts/agw-local/prepare.sh). Only the gateway is a stub (pull + burn +
fee arithmetic) installed at the UniversalGatewayPC address. Push-EOA
signers only; no UEA, TSS, relay or destination settlement.

31 tests cover create/list/derive, owner and agent doors through the public
PushChain client, maxCalls / pins / amount / expiry enforcement with decoded
policy errors, atomic rules.update (five checkpoints) and its stale-spend
rollback, revoke-all, read-only and reinitialize behaviour, CREATE_PARTIAL
recovery on the sequential path, and an agent EVM outbound that passes every
URP gate with an owner-set bounded allowance.

vectors.spec.ts writes src/lib/agentic/__fixtures__/e704d5b-vectors.json
from pure engine/factory views and real grants, so unit tests check the
codecs against values the contracts computed.
…gement

122 mock-boundary tests in 6 suites (no network): contract-vector checks for IDs and the
native session encoding, ABI-layout offsets, A01/A02/A03 boundaries,
universal-rule validation and capability gating, door resolution and wiring
checks, per-send rule selection (none / one / duplicate / revoked / RPC
failure), wallet and checkpoint reads (ordering, sinceBlock, count
mismatch, derivation drift), send guards that never reach the signer,
outbound request composition, create / add / revoke / update call shapes and
failure reporting, response replay and revert decoding.
…ps accepted

AGW SDK page §4 (outside change confirmed 2026-09-28), plan/agw step 15:

- PushChain.CONSTANTS.READ.CHAIN = { ...CHAIN, WEB2: 'web2' }, enumerable.
- CHAIN.WEB2 and READ.WEB2 become deprecated aliases with the same value
  'web2'; CHAIN still enumerates blockchains only.
- ReadChain accepts 'web2' and the legacy 'web2:https' literal; both
  normalize to the unchanged wire identity { web2, https } / caip2
  'web2:https'. Prepared and tracked reads report chain 'web2'.
- Transaction routing rejects both spellings.

Behaviour change to review: the runtime value of CHAIN.WEB2 / READ.WEB2 is
now 'web2' (was 'web2:https'). Comparisons against the constants keep
working; code comparing against the old literal does not.
Seven live AGW specs (21 scenarios) under __e2e__/agw covering create,
funding and bounded allowance, native owner/agent execution and failures,
add/update/revoke with checkpoint counts, positive-amount EVM outbound with
destination verification and replay, external EVM / first-use / Solana-origin
agents, and hook/identity behaviour through wait and trackTransaction. A
pending spec records the multi-asset and SVM-destination cases as it.todo.

Gating: specs run only with AGW_E2E=1 (set by the agw scenarios) and their
beforeAll fails with AgwPrerequisiteError unless AGW_DEPLOYMENT_MANIFEST names
a deployment whose wiring verifies on-chain, so a selected run cannot pass
vacuously. No such deployment exists yet (A07). The group is excluded from
`all` (still 76 scenarios), added to the workflow choices, and preflight
verifies the manifest read-only and exits before any funding when it is
missing. Budgets use the existing payer assets (Push master for owner gas,
wallet PC and the bounded fresh-agent funding; EVM master UEA for external
agent gas; pETH for the outbound).

Not run live: there is no compatible deployment and no authorization.
rules.add with more than one rule went through the signer's batch, which on
a Push EOA without EIP-7702 degrades to separate, non-atomic transactions —
contradicting "grants new rules under one signature" (spec 1.k) and plan
step 7.5 ("batches grants through the existing owner wallet"). Several rules
now go through one owner execute batch of self-calls; a single rule stays a
direct grant. Each batched grant ticks OWNER_ACTION before RULES_GRANTED,
verified against the real contracts in the local harness.
Adds the per-step status (unit / local real-contract / live) with A01–A08
design and artifact status, and the review handoff: revisions, changed
modules, public behaviour with its authority, exact commands and counts,
real-contract versus mock evidence, blockers and review hotspots. Commits
the implementation agent prompt the work followed and links both documents
from the planning README. No live AGW run occurred (A07).
R1  create() deploys with deployWalletWithSig(intent{owner,index,wallet}) sent
    by the owner itself: the factory reverts IndexMismatch if a concurrent
    creation took the slot, so no grant can land on a wallet this call did not
    deploy. Reported as INDEX_RACE with committed: false.
R4  The SDK no longer writes gateway allowances on either door (a write from a
    stale read could restore revoked authority, and uint256.max overflowed).
    Both doors consume an allowance the owner set separately.
R2  A ChainTarget on the connected Push chain is a native send; another Push
    network is refused instead of routed outbound.
R3  Destination calls follow core Route 2 (ERC-20 transfer to the target,
    native value to the target, arrays as given, burn sized from value).
    Requests with no destination call are refused; agent selector-less
    destination calls are refused before signing.
R5  Decoded native pins/amount use a raw { offset, expected } form, which the
    encoder accepts; argument form also accepts canonical 32-byte words.
R6  A decoded AGW outbound sets route UOA_TO_CEA authoritatively on replay.
R7  Partial-create state comes from this call's receipts; unknown outcomes
    are reported as 'unknown' and lost receipts keep the submitted hash
    (RECEIPT_UNAVAILABLE).

Also: revert decoding names errors by selector when arguments are lost, and an
omitted funds.token on an outbound means the destination native token.
Race regressions ported to __agw-local__/agw-local-races.spec.ts; review
regressions ported to the unit suites. Unit 1899 passed; harness 34 passed.
Adds the independent review package (findings, reproductions, evidence) and a
review-response section in the handoff mapping R1-R7 to fixes and evidence,
with the remaining limits. Status matrix updated; wording now says no
compatible deployment has been verified or registered.
@mohammeds1992 mohammeds1992 changed the title Feat/agw sdk v4 feat(core): add AGW v4 SDK support Oct 6, 2026
- Resolve the node-registered Circle USDC routes (Sepolia, Base, Arbitrum
  Sepolia) by exact address for agentic wallets; DEXES Sepolia and LENDING
  Arbitrum Sepolia presets become route-ready.
- AGW gas budget never attaches less than the Push pool cost plus 20%, keeps
  the over-$10 share and excludes protocolFee; BNB testnet gas is valued at
  the pool rate because no BNB/USD feed exists.
- Agent EVM sends default to 1,000,000 gas for token exports or multi-call
  payloads (the 500,000 base ran out on a Sepolia swap); omitted Solana gas
  uses route and finalize sizing.
- Refuse an explicit gasLimit below the chain base, a Solana budget still
  short after one re-quote, and a zero Solana maxGasPerCall.
- Correct the Base Sepolia WETH address.
- Add opt-in live groups (unchanged and routed presets, gas, agent SPL,
  exact routes, Solana Memo) and read-only compatibility, gas-quote and
  route-registry drift scripts.
…tions

- Independent review of the AGW creation flow with decision matrix,
  evidence and post-review addenda.
- October 20-21 preset acceptance and gas evidence, routed-preset, exact-route
  and Solana Memo live results.
- Findings verified from the deployed node, contracts and chain before asking
  the team; question drafts split for Harsh, Aman, Zaryab and core/gateway.
- Implementation status updated.
Rewrite the product and preset questions after cold-read review so each
owner has the context to decide: defined terms, worst-case transfer risk,
limit label text, route ownership, and what native wrap unblocks. Hold the
Zaryab feasibility list until Harsh picks a contract option, and put the
core/gateway questions on hold with a send-when trigger for each.
Act on the product, preset and contract answers (Harsh, Aman, Zaryab):

- Presets contain only what works: Uniswap V3 and Aave V3 on Sepolia,
  Base Sepolia and Arbitrum Sepolia. Each sends native ETH from Push and
  wraps it on arrival; DEX swaps WETH and Circle USDC on the destination
  only. get() returns { rules }: readiness and the network option are
  removed, PREDICTION and the mainnet templates are dropped, and supplied
  assets must be one ETH asset per chain with positive limits.
- Tokens-only EVM rules: ERC20 assets without allowedCalls become
  transfer calls pinned to the owner's EVM address, plus opt-in transferTo
  recipients. Native assets and Solana are refused.
- MOVEABLE.TOKEN.<CHAIN>.ALL expands to every routable token with default
  limits; utils.agentic.assets.all(chain) exposes the list. create, add
  and update take the new AuthoredRule input type; Rule is unchanged.
- Report the eight-function Push-chain limit before the generic 1..32.
- Refuse Solana fromEnd data pins on write until the policy fix.
- Decode InnerValueExceedsAllowance and BeneficiaryMismatch, which URP
  encodes by selector and its compiled ABI omits.

Tests: rewritten preset unit, local v6 and live acceptance specs (the
DEX case picks the fee tier with QuoterV2); new tokens-only/ALL unit and
live specs; the old prefunded preset fixtures are removed. All six
presets and both tokens-only/ALL cases pass live on Donut.
Record the answers from Harsh, Aman and Zaryab in the question files and
note that presets no longer use the .old routes. Update the spec mirror's
action limit (1..8 Push-chain, 1..32 other chains). Add dated entries to
the implementation status, presets log and SDK changelog, including the
live runs: six presets and tokens-only/ALL pass; one Base outbound stayed
node-PENDING after delivering and passed on re-run.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant