aere-quantum/payments
2026-10-28 00:37:27 +02:00
..
dovezi payments: the risk step and the payment receipt for people and companies (declared policy under hash, reproducible verdict with named unmeasured signals, AIP-23 settlement receipt notarized under the post-quantum anchor, public reader; measured on testnet 28001); README index 2026-10-02 20:35:06 +03:00
chitanta.mjs conformance: a conformance suite for the AIP-23 proof kinds (one verdict form over the published verifiers, 35 rules derived from code, 122 vectors, a runner for any implementation, a second verifier in Python); four defects it found in the published verifiers are fixed here: the market judge accepted a timeline with its submission event withheld, and three verifiers threw on malformed input instead of refusing by name 2026-10-03 13:26:03 +03:00
proba-plata-28001.mjs payments: the public reader of a receipt is tested on 20 named cases (was 14), including a run with no usable verifier, which now stops before reading the chain and says why (proba-plata-fara-verificator.mjs, new); proba-plata-28001.mjs exits with the reason when the verifier is missing; README counts updated (1255 files). 2026-10-28 00:30:32 +02:00
proba-plata-fara-verificator.mjs payments: proba-plata-fara-verificator.mjs needs ethers for its positive control (it starts the real flow); the README now says so (AERE_ETHERS_DIR=<dir with node_modules/ethers>) and the harness stops with that reason when ethers is missing, where it reported a confusing STRICAT. Found by running the published instructions from a fresh clone. 2026-10-28 00:37:27 +02:00
proba-risc.mjs conformance: a conformance suite for the AIP-23 proof kinds (one verdict form over the published verifiers, 35 rules derived from code, 122 vectors, a runner for any implementation, a second verifier in Python); four defects it found in the published verifiers are fixed here: the market judge accepted a timeline with its submission event withheld, and three verifiers threw on malformed input instead of refusing by name 2026-10-03 13:26:03 +03:00
proba-verifica-chitanta.mjs payments: the public reader of a receipt is tested on 20 named cases (was 14), including a run with no usable verifier, which now stops before reading the chain and says why (proba-plata-fara-verificator.mjs, new); proba-plata-28001.mjs exits with the reason when the verifier is missing; README counts updated (1255 files). 2026-10-28 00:30:32 +02:00
README.md payments: proba-plata-fara-verificator.mjs needs ethers for its positive control (it starts the real flow); the README now says so (AERE_ETHERS_DIR=<dir with node_modules/ethers>) and the harness stops with that reason when ethers is missing, where it reported a confusing STRICAT. Found by running the published instructions from a fresh clone. 2026-10-28 00:37:27 +02:00
risc.mjs conformance: a conformance suite for the AIP-23 proof kinds (one verdict form over the published verifiers, 35 rules derived from code, 122 vectors, a runner for any implementation, a second verifier in Python); four defects it found in the published verifiers are fixed here: the market judge accepted a timeline with its submission event withheld, and three verifiers threw on malformed input instead of refusing by name 2026-10-03 13:26:03 +03:00
verifica-chitanta.mjs payments: the public reader of a receipt is tested on 20 named cases (was 14), including a run with no usable verifier, which now stops before reading the chain and says why (proba-plata-fara-verificator.mjs, new); proba-plata-28001.mjs exits with the reason when the verifier is missing; README counts updated (1255 files). 2026-10-28 00:30:32 +02:00

AERE Payments: the risk step and the receipt

The two pieces that were missing from the payment chain for people and companies (identity -> authorization -> risk -> payment -> proof -> settlement -> receipt), built as pure modules on what already exists: the AIP-23 settlement envelope (proof-kinds/), the notary call of the house (agents/agent-ancora.mjs) and the AIP-23 reference verifier. Prices are in USD; the asset is only the settlement.

Risk (risc.mjs). A declared policy (definePolicy: a per-payment limit and a sliding-window limit in USD per payer, the assets allowed, the counterparties refused with the source of each entry) and the inputs of one payment (payer, payee, asset and amount, the USD rate DECLARED as an input with its source and time, the payer's history as this issuer recorded it, the time) give one verdict (judeca): ALLOW or REFUSE, the reasons, what was measured, and what was NOT. The verdict's hash covers the policy's hash and the inputs' hash, so anyone with the same policy and inputs reproduces it; a policy with a field the engine does not know is refused, so no one can be shown a rule that is not applied. The signals the module does not have are named in every verdict, never simulated: sanctions screening (no source), identity tier, device or location, chargeback history, and the payer's payments outside this issuer's own receipts. Without a declared rate the USD value is unmeasured and the policy refuses; it is never guessed.

Receipt (chitanta.mjs). An instruction (payer, payee, the amount in the asset and in USD at the declared rate, the transaction and its block, the risk verdict with its policy under hash, the unmeasured signals) and the AIP-23 settlement envelope that commits to it by hash. The envelope is what the issuer notarizes on AereNotary: the receipt's time is then the chain's, read back under a post-quantum certified anchor by the reference verifier. verificaChitanta checks that the envelope commits to the instruction, that the USD amount is exactly amount x rate, that the policy shown hashes to the one under the verdict, that the verdict reproduces from the inputs and was ALLOW, and, with the chain facts, that the transaction is this payment (from, to, value, block, status).

node proba-risc.mjs                       # 23 rows, no chain: the verdicts under a policy, a receipt verified, nine forged ones refused by name,
                                          # a malformed payment refused by name (a verdict, not an exception)
node proba-risc.mjs --control-negativ     # 10 plantings on copies of risc.mjs and chitanta.mjs; each forged fixture must then be accepted
AERE_TESTNET_KEY_FILE=<key> AERE_ETHERS_DIR=<dir with node_modules/ethers> AERE_VERIFY_PROOF=<verify-proof.mjs> node proba-plata-28001.mjs
                                          # the flow on testnet 28001; AERE_VERIFY_PROOF names the reference verifier (verify-proof.mjs as served at aere.network/tools, with verify-anchor.mjs, mpt.mjs, falcon512.mjs, registry-v3.mjs and package.json beside it and `npm install` done there),
                                          # and without a usable one the flow stops NEMASURAT before it reads or sends anything
AERE_ETHERS_DIR=<dir with node_modules/ethers> node proba-plata-fara-verificator.mjs
                                          # 4 rows, no chain: that refusal, before any request, against a local stub that counts them;
                                          # ethers starts the flow of the positive control (without it the harness stops and says so)
node verifica-chitanta.mjs dovezi/chitanta-28001-<date>.json --rpc https://testnet-rpc.aere.network --verify-proof <verify-proof.mjs>
node proba-verifica-chitanta.mjs           # 20 rows, no chain: the public reader against a local RPC stub and a stub of the reference
                                          # verifier, each exit code and verdict word as POST /v1/payments/verify gives them

Measured on 2026-10-02 on testnet 28001 (9/9): a person's payment of 0.4 tAERE at a declared 0.5 USD/tAERE = 0.20 USD allowed, paid by a plain transfer the payer signed, its receipt issued, notarized by the payee and read back with finality PASSED under a post-quantum certified anchor; a payment of 1.50 USD refused above the per-payment limit with no transaction sent; the fourth payment in the window refused above the count; the receipt forged (amount changed) INVALID; a looser policy shown under the receipt's policy hash INVALID. The public reader (verifica-chitanta.mjs) needs only Node.js, and reads the chain by plain JSON-RPC; its verdict VALID also needs the reference verifier, verify-proof.mjs as served at aere.network/tools, with verify-anchor.mjs, mpt.mjs, falcon512.mjs, registry-v3.mjs and package.json beside it and npm install done there (corrected 2026-10-27: this said the reader needs only Node.js, and verify-proof.mjs alone stops at its first import). Its file is the receipt with the policy and the inputs the issuer judged (the receiptFile of the Payments API's receipt route), and its verdicts are those of POST /v1/payments/verify: exit 0 VALID only when the transaction is compared on chain and the reference verifier finds the notarization under a post-quantum certified anchor (finality PASSED), 1 INVALID with the reasons, 2 PARTIAL when something was not measured (no --rpc, no chain answer, an RPC of another chain, no --verify-proof, a reference verifier that ran and gave no verdict, the policy or the inputs missing, finality PENDING or UNMEASURED). Corrected 2026-10-27: until this date it wrote VALID and exited 0 without --verify-proof and while the notarization was pending, and it called a file without the policy and the inputs INVALID. Corrected again the same day: an RPC of another chain was handed on to the reference verifier, which answered FAILED, so an authentic receipt came out INVALID (the envelope is now judged offline and the verdict is PARTIAL); a verifier that did not start was reported as "not run" (it is now "ran, gave no JSON", with its error line); a file that is not a receipt ended in an exception with the exit code of INVALID (it is now INVALID by name).

Every refusal names its rule, in the module's working language: rules on a risk verdict (forma, activ, contrapartida, curs, limita, fereastra, that is form, asset, counterparty, rate, limit and window; outside the hashed body, so the hash of a verdict already issued is unchanged), reguli on a receipt verdict (legatura, suma, politica, risc, lant, that is binding, amount, policy, risk and chain). The Payments API of Aere Cloud returns the risk rules under their English names since 2026-10-27, translated at its boundary. (Corrected 2026-10-27: this paragraph gave the English names as the ones the module returns.) The rate is a decimal string (a JSON number is refused, not rounded), and a history entry the engine cannot count is refused, not left out of the window. The conformance suite (conformance/) holds a vector for each of these rules and runs any implementation against them.

What it is not, and what is not measured

  • Not KYC, not AML, not sanctions screening. The policy's refused counterparties are addresses this house measured as sinks on 28001 (contracts with no path to withdraw what is sent to them, with the deployment record as source) and the zero address; no sanctions list is consulted, and the verdict says so in unmeasured. An identity or compliance record (identity/) can be named in the inputs; it is not judged here.
  • The policy is the issuer's word. One issuer, one policy, one key: the receipt proves that THIS policy, as hashed, gave THIS verdict on THESE inputs; it does not prove the policy is a good one, nor that the issuer's history of the payer is complete (it is only the issuer's own receipts).
  • The rate is declared, not observed. The USD amount is exact at the rate the issuer declares as an input (source and time on the receipt); a wrong declared rate gives a wrong USD figure, honestly attributed.
  • Native transfers only in the measured flow. An ERC-20 payment (the testnet USD token through x402) is supported by the policy's asset list but not measured; the receipt's chain check compares value only for the native asset.
  • This module is not a service. The issuer runs it in its own process, or calls the hosted Payments API of Aere Cloud, which runs these modules (POST /v1/payments/risk, /receipt, /verify, with a key); there is no queue and no callback, and nothing here moves money. (Corrected 2026-10-27: this line said "Not a payment API", while the hosted API exists.)
  • Chain 2800: nothing ran there; test keys only, the payee's derived from the payer's and never printed.