Skip to content

feat: allow service owner to settle their own service#76

Merged
mikewheeleer merged 1 commit into
Agentpay-Org:mainfrom
greatest0fallt1me:feature/contracts-13-owner-settle
Jun 24, 2026
Merged

feat: allow service owner to settle their own service#76
mikewheeleer merged 1 commit into
Agentpay-Org:mainfrom
greatest0fallt1me:feature/contracts-13-owner-settle

Conversation

@greatest0fallt1me

Copy link
Copy Markdown
Contributor

Closes #13.

Problem

settle required the global admin's require_auth(), so the owner stored in ServiceMetadata.owner could not trigger settlement for their own service — every settlement funnelled through the central admin key.

Change

settle(caller, agent, service_id) now authorizes either the admin or the registered owner of that specific service.

caller Condition Result
admin always settles
service owner caller == ServiceMetadata(service_id).owner settles
non-admin service has no metadata/owner ServiceMetadataNotFound (#13)
any other metadata exists but caller isn't owner NotPendingAdmin (#6, reused as unauthorized — matches transfer_service_ownership)

Pause gate, counter-drain semantics, and the settled event are unchanged. No new error codes. Existing settle call sites updated to pass the admin as caller (ABI adds a leading caller argument — intentional).

Tests

  • test_owner_can_settle_own_service, test_admin_can_settle_owned_service
  • test_owner_cannot_settle_other_service#6
  • test_nonadmin_settle_without_metadata_rejected#13
  • test_owner_settle_rejected_while_paused#4

cargo fmt --all -- --check, cargo build, cargo test all green — 56 passed; 0 failed.

Security notes

Owner of service A cannot settle service B; a service with no metadata is admin-only. The owner authorization is strictly scoped to the matching service_id.

Closes Agentpay-Org#13. settle required the global admin's auth, so the owner stored
in ServiceMetadata.owner could not settle their own service. Add a caller
argument and authorize settlement for either the admin OR that service's
registered owner. A non-admin caller with no service metadata is rejected
with ServiceMetadataNotFound (Agentpay-Org#13); a non-owner non-admin caller with
NotPendingAdmin (Agentpay-Org#6, reused as unauthorized). The owner of service A
cannot settle service B. Pause gate, counter-drain, and the settled event
are unchanged. Existing settle call sites updated to pass the admin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mikewheeleer mikewheeleer merged commit e18ed6d into Agentpay-Org:main Jun 24, 2026
1 check passed
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.

Support per-service owner authorization for self-service settlement

2 participants