Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/ACTPClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1805,6 +1805,18 @@ export class ACTPClient {
(agentBlock && typeof agentBlock.slug === 'string' ? agentBlock.slug : undefined) ||
(fileSlug !== 'AGIRAILS' ? fileSlug : undefined);

// AIP-18 DEC-3: a pure buyer (intent: pay) is never anchored on-chain —
// its config lives in the local file + the agirails.app DB, not the
// AgentRegistry. Chain-based drift/reconcile does not apply, so skip it
// rather than emit a misleading "not published / config ahead" warning
// on every client startup. (DB-based buyer reconcile is future work.)
const intentVal =
(typeof frontmatter.intent === 'string' ? frontmatter.intent : undefined) ||
(agentBlock && typeof agentBlock.intent === 'string' ? agentBlock.intent : undefined);
if (intentVal?.toLowerCase() === 'pay') {
return;
}

const autoSync =
process.env.ACTP_AUTO_SYNC !== '0' && process.env.ACTP_AUTO_SYNC !== 'false';

Expand Down
25 changes: 24 additions & 1 deletion src/cli/commands/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,22 @@ async function runPublish(
'Pay-only agent: skipping on-chain registration. ' +
'Identity is your wallet + agirails.app profile.'
);

// Resolve the Smart Wallet address for a wallet:auto buyer so the DB
// link (and the buyer-link marker) record the address the agent actually
// transacts from — not the bare EOA signer. Providers get this from
// on-chain activation; a buyer skips activation, so read the address
// `actp init` derived into .actp/config.json. (Falls back to the EOA if
// unknown.) This makes buyer attribution match on-chain payments.
try {
const cfg = loadConfig(projectRoot);
if (cfg.wallet === 'auto' && cfg.smartWallet) {
smartWalletAddress = cfg.smartWallet;
}
} catch {
// Best-effort — the EOA fallback below still produces a valid link.
}

// Write the buyer-link marker so the SDK's auto-wallet gate grants
// gas-sponsored transactions to this linked buyer (AIP-18 DEC-8) — a
// buyer has no on-chain configHash and no pending-publish, so without
Expand All @@ -579,7 +595,7 @@ async function runPublish(
{
version: 1,
slug: v4Config!.slug,
wallet: (walletAddress || '').toLowerCase(),
wallet: (smartWalletAddress || walletAddress || '').toLowerCase(),
linkedAt: new Date().toISOString(),
},
buyerLinkActpDir,
Expand Down Expand Up @@ -753,6 +769,13 @@ async function runPublish(
// the next re-publish.
intent: v4Config.intent,
capabilities: v4Config.services.map(s => s.type),
// Buyer-side discovery metadata (AIP-18 §7.1, opt-in semi-public)
// so the dashboard/profile reflects what the buyer requests.
// budget is deliberately NOT synced — it is a private operational
// cap (DEC-2) and never leaves the owner's machine.
...(v4Config.servicesNeeded?.length
? { services_needed: v4Config.servicesNeeded }
: {}),
pricing: {
model: "fixed",
amount: String(v4Config.pricing.base),
Expand Down
Loading