Skip to content

feat(samples): add human-present crypto-solana scenario (AP2 + Solana Pay reference binding)#228

Open
chopmob-cloud wants to merge 3 commits intogoogle-agentic-commerce:mainfrom
chopmob-cloud:feat/crypto-solana-scenario
Open

feat(samples): add human-present crypto-solana scenario (AP2 + Solana Pay reference binding)#228
chopmob-cloud wants to merge 3 commits intogoogle-agentic-commerce:mainfrom
chopmob-cloud:feat/crypto-solana-scenario

Conversation

@chopmob-cloud
Copy link
Copy Markdown

@chopmob-cloud chopmob-cloud commented Apr 24, 2026

Adds a new human-present A2A scenario: `code/samples/python/scenarios/a2a/human-present/crypto-solana/`.

What this adds

A parallel to the existing `cards`, `x402`, and open `crypto-algo` (PR #218) scenarios — settling on Solana using on-chain USDC (SPL Token) with Solana Pay `reference` pubkey binding for deterministic tx↔mandate correlation.

Why `reference` binding matters here

Solana has no native transaction memo field (unlike Algorand / Hedera), and the SPL Memo Program is inconsistently supported across wallets. The canonical Solana Pay primitive for binding a settling transaction to a specific order is a `reference` pubkey — a fresh ed25519 public key included as a read-only, non-signer account on the transfer instruction:

```
solana:?amount=&spl-token=<USDC_MINT>&reference=<burner_pubkey>&label=...&message=<mandate_id>
```

After settlement, the Merchant Payment Processor Agent resolves the transaction deterministically via `getSignaturesForAddress()`. This is:

  • Cryptographically unique per checkout (256-bit entropy)
  • Wallet-universal — every Solana Pay–compliant wallet attaches the reference automatically
  • Non-interactive from the buyer's side — no need to paste a tx signature back

Scope

Minimal and additive — two files under `code/samples/python/scenarios/a2a/human-present/crypto-solana/`:

  • `README.md` — full flow documentation including env var reference
  • `run.sh` — launcher (starts Merchant, CP, MPP agents, then Shopping Agent via ADK web)

Uses the shared role agents already in `code/samples/python/src/roles/`. No changes to existing files.

Prerequisites

```
GOOGLE_API_KEY or GOOGLE_GENAI_USE_VERTEXAI=true
ALGOVOI_API_KEY # sign up at https://cloud.algovoi.co.uk
SOLANA_RPC_URL # defaults to public mainnet endpoint if not set
```

Happy to sign the Google CLA as per PR #218.

@chopmob-cloud chopmob-cloud requested a review from a team as a code owner April 24, 2026 11:44
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new sample scenario for human-present transactions using on-chain Solana USDC, including a detailed README on the Solana Pay reference binding mechanism and a shell script to orchestrate the necessary agents. Feedback was provided regarding the order of environment variable sourcing in the startup script to prevent unintended overrides from local configuration files and to improve the robustness of the cleanup process by initializing process tracking earlier.

Comment on lines +12 to +27
export PAYMENT_METHOD=CRYPTO_SOLANA

AGENTS_DIR="samples/python/src/roles"
LOG_DIR=".logs"

if [ ! -d "$AGENTS_DIR" ]; then
echo "Error: Directory '$AGENTS_DIR' not found."
echo "Please run this script from the root of the repository."
exit 1
fi

if [ -f .env ]; then
set -a
source .env
set +a
fi
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The PAYMENT_METHOD environment variable is set at line 12, but then .env is sourced at line 25. If the user has PAYMENT_METHOD defined in their .env file, it will override the scenario-specific value (CRYPTO_SOLANA), potentially causing the script to execute with the wrong payment logic. It is safer to source the .env file first and then set scenario-specific overrides. Additionally, initializing the pids array early ensures that the cleanup trap (line 80) is always safe even if the script fails during early setup (e.g., line 20).

Suggested change
export PAYMENT_METHOD=CRYPTO_SOLANA
AGENTS_DIR="samples/python/src/roles"
LOG_DIR=".logs"
if [ ! -d "$AGENTS_DIR" ]; then
echo "Error: Directory '$AGENTS_DIR' not found."
echo "Please run this script from the root of the repository."
exit 1
fi
if [ -f .env ]; then
set -a
source .env
set +a
fi
if [ -f .env ]; then
set -a
source .env
set +a
fi
export PAYMENT_METHOD=CRYPTO_SOLANA
AGENTS_DIR="samples/python/src/roles"
LOG_DIR=".logs"
pids=()
if [ ! -d "$AGENTS_DIR" ]; then
echo "Error: Directory '$AGENTS_DIR' not found."
echo "Please run this script from the root of the repository."
exit 1
fi

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already addressed in the current commit. PAYMENT_METHOD=CRYPTO_SOLANA is exported on line 13, before .env is processed. The while IFS= loop then uses [[ -v "$key" ]] to skip any variable that is already present in the environment — so a PAYMENT_METHOD entry in .env cannot override the scenario value. The result is identical to your suggestion (scenario value always wins) but the guard applies to every variable, not just PAYMENT_METHOD.

@chopmob-cloud chopmob-cloud force-pushed the feat/crypto-solana-scenario branch from 8557f75 to 3155852 Compare April 26, 2026 11:58
@chopmob-cloud
Copy link
Copy Markdown
Author

Thanks for the review @gemini-code-assist. Both points addressed in the latest commit:

  • Env var sourcing order: replaced set -a; source .env; set +a with a while IFS= loop that skips any variable already present in the calling environment. This means shell-exported variables always take precedence over values in .env, rather than being silently overwritten.

  • Process tracking initialisation: moved pids=() to before the cleanup() function definition and trap cleanup EXIT, so the cleanup handler is safe to call at any point in the script's lifecycle — including early exits during uv sync.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Thanks for the update, @chopmob-cloud. The changes to the environment variable sourcing and the process tracking initialization look solid and address the concerns raised. The use of a while loop for .env sourcing is a much safer approach, and moving the pids initialization ensures the cleanup function is robust against early exits. This looks good to go.

… Pay reference binding)

Adds a new human-present A2A scenario settling on-chain USDC on Solana,
parallel to the existing cards, x402, and crypto-algo scenarios.

## What this adds

  code/samples/python/scenarios/a2a/human-present/crypto-solana/
    README.md  — full flow documentation
    run.sh     — launcher script (starts Merchant, CP, MPP, Shopping Agent)

## Key design choice: Solana Pay reference pubkey binding

Solana has no native memo field with reliable wallet support across all
agentic clients. This scenario uses a Solana Pay 'reference' pubkey as
the on-chain binding primitive: a fresh ed25519 pubkey is generated per
checkout and included as a non-signer account on the SPL USDC transfer.

  solana:<recipient>?amount=<x>&spl-token=<USDC_MINT>&reference=<burner_pubkey>

After settlement the Merchant Payment Processor Agent resolves the
transaction deterministically via getSignaturesForAddress(reference).
This is wallet-universal, agent-friendly, and cryptographically unique
per checkout without amount-uniqueness gymnastics.

## Prerequisites

  GOOGLE_API_KEY or GOOGLE_GENAI_USE_VERTEXAI=true
  ALGOVOI_API_KEY (sign up at https://cloud.algovoi.co.uk)
  SOLANA_RPC_URL  (defaults to public mainnet endpoint)
@chopmob-cloud chopmob-cloud force-pushed the feat/crypto-solana-scenario branch from 6c884bf to e4b7a88 Compare April 29, 2026 16:15
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