Skip to content
Integra Agentic Connectors

@integraledger/profile-facilitator

The facilitator's exports, HTTP API, reason codes, storage schema, bounds and logs.

Exports

The package's entry point exports:

ExportKindWhat it is
serveProfileFacilitator(config)(c: ProfileFacilitatorConfig) => Promise<{ close(): Promise<void> }>Opens the store, starts the HTTP server and resolves once it listens.
ProfileFacilitatorConfiginterfaceThe configuration: see Run the profile facilitator.
VerifyAnswertype{isValid: true, payer} or {isValid: false, invalidReason, payer?}.
SettleAnswertype{success: true, transaction, network, payer} or {success: false, errorReason, transaction, network}.

The generated declarations are in the API reference.

HTTP API

RequestAnswer
GET /supported200 {kinds, extensions: [], signers: {}}, one kind per configured network.
POST /verify200 with a VerifyAnswer; 400 {isValid: false, invalidReason: "invalid_payload"} when the body is not JSON.
POST /settle200 with a SettleAnswer; 400 with errorReason invalid_payload when the body is not JSON.
A body over 64 KiB413, and the connection is closed.
Another method on a served path405 {error}.
Any other path404 {error}.

The facilitator has no authentication of its own. Serve it on a private interface, or behind your own network controls, to the resource servers that use it.

Reasons

Reason/verify/settleMeaning
invalid_x402_versionyesyesx402Version is not 2 in the request or the payload.
unsupported_schemeyesyesscheme is not "exact".
invalid_networkyesyesThe network is not one this facilitator is configured with.
invalid_payment_requirementsyesyesThe requirements are not ones the profile admits.
invalid_payloadyesyesThe payload does not match the profile or the requirements, or its signature or expiration fails.
unsupported_permissionyesyesTron: the transaction carries more than one signature.
invalid_transactionyesyesThe node refuses the transaction in simulation or validation.
unexpected_verify_erroryesnoThe node could not be read.
unexpected_settle_errornoyesThe node could not be read before submission, or refused the submission.
settlement_pendingnoyesSubmitted, and not yet final when the wait ended.
invalid_transaction_statenoyesIncluded and failed, or it can never be included.

unsupported_permission and invalid_transaction are this facilitator's, for a multi-signature Tron owner and for a transaction the node refuses in simulation or validation. The others are the x402 specification's.

Storage

Postgres holds one table, created at start:

CREATE TABLE IF NOT EXISTS settlement (
  network text NOT NULL,
  id text NOT NULL,
  answer jsonb,
  until timestamptz NOT NULL,
  since bigint,
  PRIMARY KEY (network, id)
)
  • One row per settled payment, keyed by network and transaction id (Tron) or extrinsic hash (Polkadot).
  • answer is null while the row is claimed and the answer is not yet written. A final answer is never replaced; a pending one is replaced by what a later read of the chain shows.
  • until is the end of the payment's validity window: Tron's expiration, or the end of the Polkadot era. A row is kept for 24 hours after it, so a repeat in that time reads the stored answer before anything is verified again. A sweep every minute drops older rows.
  • since is, for Polkadot, the first block not yet shown at finality to lack the extrinsic.
  • The pool holds at most 10 connections. Acquiring a connection, each query and each statement are bounded by 5 seconds.

Bounds and logs

  • Each node call has a timeout of at most 5 seconds and an answer of at most 4 MiB.
  • A request body is at most 64 KiB. The server's request timeout is settleWaitMs plus 60 seconds.
  • The facilitator writes one JSON line on standard error for what the operator should see and the answer does not carry: settlement-failed (with the events or receipt result the chain shows), settlement-expired and answer-not-stored.
Edit on GitHub

Last updated on

On this page