@stellar-agent-services/payment-client 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +97 -2
- package/dist/browser-storage.d.ts +4 -0
- package/dist/browser-storage.d.ts.map +1 -0
- package/dist/browser-storage.js +77 -0
- package/dist/browser-storage.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +336 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +138 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +522 -0
- package/dist/client.js.map +1 -0
- package/dist/conformance.d.ts +21 -0
- package/dist/conformance.d.ts.map +1 -0
- package/dist/conformance.js +106 -0
- package/dist/conformance.js.map +1 -0
- package/dist/file-storage.d.ts +4 -0
- package/dist/file-storage.d.ts.map +1 -0
- package/dist/file-storage.js +54 -0
- package/dist/file-storage.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/journal.d.ts +49 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +100 -0
- package/dist/journal.js.map +1 -0
- package/dist/local-key-signer.d.ts +4 -0
- package/dist/local-key-signer.d.ts.map +1 -0
- package/dist/local-key-signer.js +8 -0
- package/dist/local-key-signer.js.map +1 -0
- package/dist/manifest.d.ts +11 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +50 -0
- package/dist/manifest.js.map +1 -0
- package/dist/onchain.d.ts +17 -0
- package/dist/onchain.d.ts.map +1 -0
- package/dist/onchain.js +75 -0
- package/dist/onchain.js.map +1 -0
- package/dist/policy.d.ts +63 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +78 -0
- package/dist/policy.js.map +1 -0
- package/dist/strategies.d.ts +40 -0
- package/dist/strategies.d.ts.map +1 -0
- package/dist/strategies.js +12 -0
- package/dist/strategies.js.map +1 -0
- package/dist/verification.d.ts +29 -0
- package/dist/verification.d.ts.map +1 -0
- package/dist/verification.js +26 -0
- package/dist/verification.js.map +1 -0
- package/dist/x402-exact-stellar.d.ts +11 -0
- package/dist/x402-exact-stellar.d.ts.map +1 -0
- package/dist/x402-exact-stellar.js +17 -0
- package/dist/x402-exact-stellar.js.map +1 -0
- package/package.json +52 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stellar Agent Services contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,98 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @stellar-agent-services/payment-client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The buyer side: approval, spending policy, a hash-chained journal, payment and job recovery. The design is in
|
|
4
|
+
[docs/payment-client.md](../../docs/payment-client.md).
|
|
5
|
+
|
|
6
|
+
**Status: proof of concept.** The core flow works end to end on Stellar testnet with the built-in signer and
|
|
7
|
+
payment method, both in Node (the `stellar-pay` CLI) and in the browser (the minimal web page in
|
|
8
|
+
[apps/wallet](../../apps/wallet)). The MCP server, browser-wallet and passkey signers come later and reuse this core.
|
|
9
|
+
|
|
10
|
+
Signers and payment methods are strategies: the core keeps every safety step, and adapters for other wallets or
|
|
11
|
+
payment infrastructure plug in without changing it (docs/payment-client.md, "Strategies"). To build one, see
|
|
12
|
+
[docs/client-integration](../../docs/client-integration/README.md).
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
const client = new PaymentClient({
|
|
16
|
+
signer: localKeySigner(secret, "stellar:testnet"), // or a wallet adapter
|
|
17
|
+
methods: [x402ExactStellar()], // the default
|
|
18
|
+
policy, journal, secrets,
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The main entry point runs in Node and the browser. Journal storage depends on where it runs:
|
|
23
|
+
|
|
24
|
+
| Entry point | Contents |
|
|
25
|
+
| --- | --- |
|
|
26
|
+
| `@stellar-agent-services/payment-client` | The core, the built-in signer and payment method |
|
|
27
|
+
| `…/node` | `fileJournalStorage`, `fileSecretStore`: files only the owner can read |
|
|
28
|
+
| `…/browser` | `indexedDbJournalStorage`, `indexedDbSecretStore`: IndexedDB with strict durability |
|
|
29
|
+
| `…/conformance` | The checks every adapter must pass |
|
|
30
|
+
|
|
31
|
+
| File | Contents |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `src/client.ts` | `PaymentClient`: `quote()` (nothing signed), `pay()` (signs once), `decline()`, `recover()` (never pays) |
|
|
34
|
+
| `src/strategies.ts` | The `Signer` and `PaymentMethod` interfaces |
|
|
35
|
+
| `src/local-key-signer.ts` | The built-in signer: a secret key in this process |
|
|
36
|
+
| `src/x402-exact-stellar.ts` | The built-in payment method: x402 `exact` on Stellar, the only one Provider Standard v1 allows |
|
|
37
|
+
| `src/conformance.ts` | Checks that every signer and payment-method adapter must pass (`./conformance` entry point) |
|
|
38
|
+
| `src/policy.ts` | Spending policy with ERC-8196 field names; `checkPolicy()` fails closed |
|
|
39
|
+
| `src/verification.ts` | Application-trusted verification source; binds evidence to the approved manifest, payee, network and validity window [V1] |
|
|
40
|
+
| `src/journal.ts` | Append-only, hash-chained journal; job tokens kept apart in a `SecretStore` |
|
|
41
|
+
| `src/file-storage.ts` | Journal and job-token storage in files (`./node` entry point) |
|
|
42
|
+
| `src/browser-storage.ts` | Journal and job-token storage in IndexedDB (`./browser` entry point) |
|
|
43
|
+
| `src/manifest.ts` | Fetches and validates a provider manifest |
|
|
44
|
+
| `src/onchain.ts` | Confirms the settlement transaction on chain |
|
|
45
|
+
| `src/cli.ts` | `stellar-pay`, the PoC surface |
|
|
46
|
+
|
|
47
|
+
## Try it on testnet
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install && npm run build
|
|
51
|
+
|
|
52
|
+
# A provider wallet (it only needs a USDC trustline) and a payer wallet with testnet USDC.
|
|
53
|
+
STELLAR_PAY_HOME=~/.stellar-pay-provider npx stellar-pay wallet create
|
|
54
|
+
STELLAR_PAY_HOME=~/.stellar-pay-provider npx stellar-pay wallet fund --usdc 0
|
|
55
|
+
npx stellar-pay wallet create
|
|
56
|
+
npx stellar-pay wallet fund --usdc 2 # buys testnet USDC on the testnet DEX
|
|
57
|
+
|
|
58
|
+
# The sample provider, paid to the provider wallet's address.
|
|
59
|
+
PAY_TO=G... node examples/paid-service/dist/server.js
|
|
60
|
+
|
|
61
|
+
# Pay, with an approval prompt.
|
|
62
|
+
MANIFEST=http://localhost:8787/.well-known/stellar-agent-services.json
|
|
63
|
+
npx stellar-pay services $MANIFEST --dev
|
|
64
|
+
npx stellar-pay pay $MANIFEST text-stats '{"text":"Hello agents."}' --dev
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Job Recovery: start the provider with `DRILL_LOSE_RESPONSE=1 REPORT_DELAY_SECONDS=8`, pay `delayed-report`,
|
|
68
|
+
then run the `stellar-pay recover <job-id> --dev` command it prints. `stellar-pay jobs` and
|
|
69
|
+
`stellar-pay journal verify` show the journal.
|
|
70
|
+
|
|
71
|
+
`followPaymentUncertain: true` optionally follows an uncertain job within `followSeconds` while the provider
|
|
72
|
+
reconciles it [J13]. It only reads the original job and never pays again [J11]. The default returns uncertainty
|
|
73
|
+
immediately, so a UI can offer manual recovery. `provider-kit try` enables the bounded wait.
|
|
74
|
+
|
|
75
|
+
## Verification policy
|
|
76
|
+
|
|
77
|
+
Configured verification limits are checked at `quote()` and again at `pay()`, before signing [V1]. Install a
|
|
78
|
+
`verificationSource` in `PaymentClientOptions` to supply authenticated evidence. Without a source, or when it
|
|
79
|
+
returns missing, stale, mismatched or unreadable evidence, a payment requiring verification is blocked.
|
|
80
|
+
|
|
81
|
+
- `minVerificationScore` keeps ERC-8196's name and meaning: the **maximum allowed risk score**, 0–100, lower is
|
|
82
|
+
safer. It compares with the source's `riskScore`, not a receipt's higher-is-better conformance score.
|
|
83
|
+
- `stellar.minProviderLevel` is the minimum Provider Standard §8 level, 0–3.
|
|
84
|
+
- Even a configured value of zero requires evidence. Leaving both fields unset requires no source.
|
|
85
|
+
- Sources are trusted application code. They must authenticate validators and receipt/registry data, bind the
|
|
86
|
+
answer to the requested subject, set `checkedAt` and `expiresAt`, and bound their network calls. Never use a
|
|
87
|
+
provider's own claims as proof. No built-in registry/risk-source adapter is supplied yet.
|
|
88
|
+
- Recovery collects an already paid job without consulting the source or signing again [J11], [J13].
|
|
89
|
+
|
|
90
|
+
See [the design](../../docs/payment-client.md#verification-source) for the interface and trust boundary.
|
|
91
|
+
|
|
92
|
+
## Not done in the PoC
|
|
93
|
+
|
|
94
|
+
- No built-in Validation Registry or ERC-8126 risk-source adapter. Configured verification limits fail closed
|
|
95
|
+
until the application supplies its own trusted source.
|
|
96
|
+
- The wallet secret is a plain file (mode 600). Testnet only.
|
|
97
|
+
- No MCP server yet.
|
|
98
|
+
- Only the built-in signer and method. Adapters for other wallets come later, each in its own package.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { JournalStorage, SecretStore } from "./journal.js";
|
|
2
|
+
export declare function indexedDbJournalStorage(database?: string): JournalStorage;
|
|
3
|
+
export declare function indexedDbSecretStore(database?: string): SecretStore;
|
|
4
|
+
//# sourceMappingURL=browser-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-storage.d.ts","sourceRoot":"","sources":["../src/browser-storage.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAShE,wBAAgB,uBAAuB,CAAC,QAAQ,SAAmB,GAAG,cAAc,CAUnF;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,SAAmB,GAAG,WAAW,CAU7E"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Browser storage for the journal and job tokens: IndexedDB, readable only by the page's origin. The
|
|
2
|
+
// "./browser" entry point; Node uses file-storage.ts instead.
|
|
3
|
+
//
|
|
4
|
+
// Writes commit with strict durability, so `sending` is on disk before the paid request goes out. One
|
|
5
|
+
// writer at a time, as with the file storage: a page that can be open in several tabs holds a Web Lock
|
|
6
|
+
// while it uses the journal (apps/wallet does).
|
|
7
|
+
/** Matches the CLI's ~/.stellar-pay. */
|
|
8
|
+
const DEFAULT_DATABASE = "stellar-pay";
|
|
9
|
+
const JOURNAL = "journal";
|
|
10
|
+
const TOKENS = "job-tokens";
|
|
11
|
+
const databases = new Map();
|
|
12
|
+
export function indexedDbJournalStorage(database = DEFAULT_DATABASE) {
|
|
13
|
+
return {
|
|
14
|
+
async readLines() {
|
|
15
|
+
const store = (await open(database)).transaction(JOURNAL).objectStore(JOURNAL);
|
|
16
|
+
return (await request(store.getAll()));
|
|
17
|
+
},
|
|
18
|
+
async appendLine(line) {
|
|
19
|
+
await commit(await open(database), JOURNAL, (store) => store.add(line));
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function indexedDbSecretStore(database = DEFAULT_DATABASE) {
|
|
24
|
+
return {
|
|
25
|
+
async get(jobId) {
|
|
26
|
+
const store = (await open(database)).transaction(TOKENS).objectStore(TOKENS);
|
|
27
|
+
return (await request(store.get(jobId)));
|
|
28
|
+
},
|
|
29
|
+
async set(jobId, token) {
|
|
30
|
+
await commit(await open(database), TOKENS, (store) => store.put(token, jobId));
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function open(name) {
|
|
35
|
+
let database = databases.get(name);
|
|
36
|
+
if (database === undefined) {
|
|
37
|
+
database = new Promise((resolve, reject) => {
|
|
38
|
+
const opening = indexedDB.open(name, 1);
|
|
39
|
+
opening.onupgradeneeded = () => {
|
|
40
|
+
// Keys count up, so reading the store returns the lines in the order they were appended.
|
|
41
|
+
opening.result.createObjectStore(JOURNAL, { autoIncrement: true });
|
|
42
|
+
opening.result.createObjectStore(TOKENS);
|
|
43
|
+
};
|
|
44
|
+
opening.onsuccess = () => {
|
|
45
|
+
const db = opening.result;
|
|
46
|
+
// Another tab is upgrading or deleting the database: let it, and reopen on the next call.
|
|
47
|
+
db.onversionchange = () => {
|
|
48
|
+
db.close();
|
|
49
|
+
databases.delete(name);
|
|
50
|
+
};
|
|
51
|
+
resolve(db);
|
|
52
|
+
};
|
|
53
|
+
opening.onerror = () => {
|
|
54
|
+
databases.delete(name);
|
|
55
|
+
reject(opening.error ?? new Error(`the "${name}" database could not be opened`));
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
databases.set(name, database);
|
|
59
|
+
}
|
|
60
|
+
return database;
|
|
61
|
+
}
|
|
62
|
+
/** Resolves once the write is committed to disk. */
|
|
63
|
+
function commit(db, storeName, write) {
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const transaction = db.transaction(storeName, "readwrite", { durability: "strict" });
|
|
66
|
+
transaction.oncomplete = () => resolve();
|
|
67
|
+
transaction.onabort = () => reject(transaction.error ?? new Error("the write was aborted"));
|
|
68
|
+
write(transaction.objectStore(storeName));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function request(pending) {
|
|
72
|
+
return new Promise((resolve, reject) => {
|
|
73
|
+
pending.onsuccess = () => resolve(pending.result);
|
|
74
|
+
pending.onerror = () => reject(pending.error ?? new Error("the read failed"));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=browser-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-storage.js","sourceRoot":"","sources":["../src/browser-storage.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// stellar-pay: the PoC surface on top of the payment-client core (docs/payment-client.md).
|
|
3
|
+
//
|
|
4
|
+
// The key is a local file (the "local key" signer), which is fine for testnet and development.
|
|
5
|
+
// The web app, browser wallets and passkeys come later; they reuse the same core.
|
|
6
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { createInterface } from "node:readline/promises";
|
|
10
|
+
import { parseArgs } from "node:util";
|
|
11
|
+
import { Asset, Horizon, Keypair, Networks, Operation, TransactionBuilder } from "@stellar/stellar-sdk";
|
|
12
|
+
import { PaymentClient, PaymentRefusedError, PaymentUncertainError, ProviderBusyError, } from "./client.js";
|
|
13
|
+
import { fileJournalStorage, fileSecretStore } from "./file-storage.js";
|
|
14
|
+
import { Journal, verifyChain } from "./journal.js";
|
|
15
|
+
import { localKeySigner } from "./local-key-signer.js";
|
|
16
|
+
import { loadManifest } from "./manifest.js";
|
|
17
|
+
import { explorerUrl } from "./onchain.js";
|
|
18
|
+
import { defaultPolicy } from "./policy.js";
|
|
19
|
+
const HOME = process.env["STELLAR_PAY_HOME"] ?? join(homedir(), ".stellar-pay");
|
|
20
|
+
const NETWORK = "stellar:testnet";
|
|
21
|
+
const HORIZON = "https://horizon-testnet.stellar.org";
|
|
22
|
+
const USDC = new Asset("USDC", "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5");
|
|
23
|
+
const files = {
|
|
24
|
+
wallet: join(HOME, "wallet.json"),
|
|
25
|
+
policy: join(HOME, "policy.json"),
|
|
26
|
+
journal: join(HOME, "journal.jsonl"),
|
|
27
|
+
tokens: join(HOME, "job-tokens.json"),
|
|
28
|
+
};
|
|
29
|
+
const HELP = `stellar-pay: pay Provider Standard services on Stellar testnet (proof of concept)
|
|
30
|
+
|
|
31
|
+
wallet create create a local testnet key in ${HOME}
|
|
32
|
+
wallet fund [--usdc 5] friendbot XLM, a USDC trustline, and buy USDC on the testnet DEX
|
|
33
|
+
wallet show the address and balances
|
|
34
|
+
policy show the spending policy
|
|
35
|
+
policy set [--max-tx 0.10] [--max-day 1.00] [--auto-approve 0] [--allow-payee G...] [--block-payee G...]
|
|
36
|
+
services <manifest-url> list a provider's services and prices
|
|
37
|
+
pay <manifest-url> <service> <json-input> [--yes]
|
|
38
|
+
quote, approve, pay once, and show the result
|
|
39
|
+
recover <job-id> collect a job after a lost response, without paying again
|
|
40
|
+
jobs list jobs from the journal
|
|
41
|
+
journal verify check the journal's hash chain
|
|
42
|
+
|
|
43
|
+
--dev accept http://localhost providers`;
|
|
44
|
+
async function main() {
|
|
45
|
+
const { positionals, values } = parseArgs({
|
|
46
|
+
allowPositionals: true,
|
|
47
|
+
options: {
|
|
48
|
+
dev: { type: "boolean", default: false },
|
|
49
|
+
yes: { type: "boolean", default: false },
|
|
50
|
+
usdc: { type: "string", default: "5" },
|
|
51
|
+
"max-tx": { type: "string" },
|
|
52
|
+
"max-day": { type: "string" },
|
|
53
|
+
"auto-approve": { type: "string" },
|
|
54
|
+
"allow-payee": { type: "string", multiple: true },
|
|
55
|
+
"block-payee": { type: "string", multiple: true },
|
|
56
|
+
help: { type: "boolean", short: "h", default: false },
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
const [command, ...rest] = positionals;
|
|
60
|
+
const key = `${command ?? ""} ${rest[0] ?? ""}`.trim();
|
|
61
|
+
if (values.help || command === undefined)
|
|
62
|
+
return console.log(HELP);
|
|
63
|
+
if (key === "wallet create")
|
|
64
|
+
return walletCreate();
|
|
65
|
+
if (key === "wallet fund")
|
|
66
|
+
return walletFund(values.usdc);
|
|
67
|
+
if (command === "wallet")
|
|
68
|
+
return walletShow();
|
|
69
|
+
if (key === "policy set")
|
|
70
|
+
return policySet(values);
|
|
71
|
+
if (command === "policy")
|
|
72
|
+
return console.log(JSON.stringify(await readPolicy(), null, 2));
|
|
73
|
+
if (command === "services")
|
|
74
|
+
return listServices(arg(rest, 0, "manifest-url"), values.dev);
|
|
75
|
+
if (command === "pay")
|
|
76
|
+
return pay(arg(rest, 0, "manifest-url"), arg(rest, 1, "service"), arg(rest, 2, "json-input"), values);
|
|
77
|
+
if (command === "recover")
|
|
78
|
+
return recover(arg(rest, 0, "job-id"), values.dev);
|
|
79
|
+
if (command === "jobs")
|
|
80
|
+
return listJobs();
|
|
81
|
+
if (key === "journal verify")
|
|
82
|
+
return journalVerify();
|
|
83
|
+
throw new Error(`unknown command "${positionals.join(" ")}"\n\n${HELP}`);
|
|
84
|
+
}
|
|
85
|
+
// ── wallet ──────────────────────────────────────────────────────────────────
|
|
86
|
+
async function walletCreate() {
|
|
87
|
+
if (await exists(files.wallet))
|
|
88
|
+
throw new Error(`a wallet already exists in ${files.wallet}`);
|
|
89
|
+
const keypair = Keypair.random();
|
|
90
|
+
const wallet = { version: 1, network: NETWORK, address: keypair.publicKey(), secret: keypair.secret() };
|
|
91
|
+
await mkdir(HOME, { recursive: true, mode: 0o700 });
|
|
92
|
+
await writeFile(files.wallet, JSON.stringify(wallet, null, 2), { mode: 0o600 });
|
|
93
|
+
await writeFile(files.policy, JSON.stringify(defaultPolicy(wallet.address, NETWORK), null, 2), { mode: 0o600 });
|
|
94
|
+
console.log(`Created a testnet wallet: ${wallet.address}`);
|
|
95
|
+
console.log(`Next: stellar-pay wallet fund`);
|
|
96
|
+
}
|
|
97
|
+
async function walletFund(usdc) {
|
|
98
|
+
const wallet = await readWallet();
|
|
99
|
+
const horizon = new Horizon.Server(HORIZON);
|
|
100
|
+
let account = await horizon.loadAccount(wallet.address).catch(() => undefined);
|
|
101
|
+
if (account === undefined) {
|
|
102
|
+
console.log("Asking friendbot for testnet XLM…");
|
|
103
|
+
const response = await fetch(`https://friendbot.stellar.org/?addr=${wallet.address}`);
|
|
104
|
+
if (!response.ok)
|
|
105
|
+
throw new Error(`friendbot answered ${response.status}`);
|
|
106
|
+
account = await horizon.loadAccount(wallet.address);
|
|
107
|
+
}
|
|
108
|
+
const hasTrustline = account.balances.some((b) => "asset_code" in b && b.asset_code === USDC.code && b.asset_issuer === USDC.issuer);
|
|
109
|
+
const builder = new TransactionBuilder(account, { fee: "1000", networkPassphrase: Networks.TESTNET }).setTimeout(60);
|
|
110
|
+
if (!hasTrustline)
|
|
111
|
+
builder.addOperation(Operation.changeTrust({ asset: USDC }));
|
|
112
|
+
if (Number(usdc) > 0) {
|
|
113
|
+
builder.addOperation(Operation.pathPaymentStrictReceive({ sendAsset: Asset.native(), sendMax: "1000", destination: wallet.address, destAsset: USDC, destAmount: usdc, path: [] }));
|
|
114
|
+
}
|
|
115
|
+
if (hasTrustline && Number(usdc) <= 0)
|
|
116
|
+
return walletShow();
|
|
117
|
+
const transaction = builder.build();
|
|
118
|
+
transaction.sign(Keypair.fromSecret(wallet.secret));
|
|
119
|
+
console.log(`${hasTrustline ? "" : "Adding a USDC trustline. "}${Number(usdc) > 0 ? `Buying ${usdc} USDC on the testnet DEX.` : ""}`);
|
|
120
|
+
const result = await horizon.submitTransaction(transaction);
|
|
121
|
+
console.log(`Done: ${explorerUrl(NETWORK, result.hash)}`);
|
|
122
|
+
await walletShow();
|
|
123
|
+
}
|
|
124
|
+
async function walletShow() {
|
|
125
|
+
const wallet = await readWallet();
|
|
126
|
+
console.log(`Address ${wallet.address} (${wallet.network})`);
|
|
127
|
+
const account = await new Horizon.Server(HORIZON).loadAccount(wallet.address).catch(() => undefined);
|
|
128
|
+
if (account === undefined)
|
|
129
|
+
return console.log("Not funded yet. Run: stellar-pay wallet fund");
|
|
130
|
+
for (const balance of account.balances) {
|
|
131
|
+
const name = balance.asset_type === "native" ? "XLM" : "asset_code" in balance ? balance.asset_code : balance.asset_type;
|
|
132
|
+
console.log(`${name.padEnd(8)} ${balance.balance}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// ── policy ──────────────────────────────────────────────────────────────────
|
|
136
|
+
async function policySet(values) {
|
|
137
|
+
const policy = await readPolicy();
|
|
138
|
+
if (typeof values["max-tx"] === "string")
|
|
139
|
+
policy.maxValuePerTx = toBaseUnits(values["max-tx"]);
|
|
140
|
+
if (typeof values["max-day"] === "string")
|
|
141
|
+
policy.maxValuePerDay = toBaseUnits(values["max-day"]);
|
|
142
|
+
if (typeof values["auto-approve"] === "string")
|
|
143
|
+
policy.stellar.autoApproveUpTo = toBaseUnits(values["auto-approve"], true);
|
|
144
|
+
const allow = values["allow-payee"];
|
|
145
|
+
const block = values["block-payee"];
|
|
146
|
+
if (allow !== undefined)
|
|
147
|
+
policy.stellar.payees.allow = [...(policy.stellar.payees.allow ?? []), ...allow];
|
|
148
|
+
if (block !== undefined)
|
|
149
|
+
policy.stellar.payees.block = [...policy.stellar.payees.block, ...block];
|
|
150
|
+
await writeFile(files.policy, JSON.stringify(policy, null, 2), { mode: 0o600 });
|
|
151
|
+
console.log(`Per payment ${usdc(policy.maxValuePerTx)} · per 24 h ${usdc(policy.maxValuePerDay)} · ` +
|
|
152
|
+
`no prompt up to ${usdc(policy.stellar.autoApproveUpTo)}`);
|
|
153
|
+
}
|
|
154
|
+
// ── paying ──────────────────────────────────────────────────────────────────
|
|
155
|
+
async function listServices(manifestUrl, dev) {
|
|
156
|
+
const manifest = await loadManifest(manifestUrl, { allowLocalhost: dev });
|
|
157
|
+
const option = manifest.payment.accepts[0];
|
|
158
|
+
console.log(`${manifest.provider.name} · ${option.network} · pays ${short(option.payTo)}\n`);
|
|
159
|
+
for (const service of manifest.services) {
|
|
160
|
+
console.log(`${service.name.padEnd(20)} ${usdc(service.price.amount).padEnd(12)} ${service.charge ?? "upfront"}`);
|
|
161
|
+
console.log(`${"".padEnd(20)} ${service.description}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async function pay(manifestUrl, serviceName, inputText, values) {
|
|
165
|
+
let input;
|
|
166
|
+
try {
|
|
167
|
+
input = JSON.parse(inputText);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
throw new Error(`the input must be a JSON object, such as '{"text":"hello"}'`);
|
|
171
|
+
}
|
|
172
|
+
const client = await openClient(values.dev);
|
|
173
|
+
const quote = await client.quote(manifestUrl, serviceName, input);
|
|
174
|
+
showQuote(quote, client);
|
|
175
|
+
if (!client.payable(quote)) {
|
|
176
|
+
console.log("\n✗ Blocked. Nothing was signed or paid.");
|
|
177
|
+
process.exitCode = 1;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
let approved = !quote.needsApproval || values.yes;
|
|
181
|
+
if (quote.needsApproval && !values.yes)
|
|
182
|
+
approved = await confirm("\nApprove this exact payment? [y/N] ");
|
|
183
|
+
if (!quote.needsApproval)
|
|
184
|
+
console.log("\nInside your auto-approve budget: paying without a prompt.");
|
|
185
|
+
try {
|
|
186
|
+
showResult(await client.pay(quote, { approved }));
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (error instanceof PaymentRefusedError || error instanceof ProviderBusyError) {
|
|
190
|
+
console.log(`\n✗ Not paid: ${error.message}`);
|
|
191
|
+
process.exitCode = 1;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (error instanceof PaymentUncertainError) {
|
|
195
|
+
console.log(`\n⚠ ${error.message}`);
|
|
196
|
+
console.log(` Run: stellar-pay recover ${error.jobId}${values.dev ? " --dev" : ""}`);
|
|
197
|
+
process.exitCode = 2;
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async function recover(jobId, dev) {
|
|
204
|
+
const client = await openClient(dev);
|
|
205
|
+
console.log(`Recovering ${jobId} with check-status / get-result. No payment is sent.`);
|
|
206
|
+
showResult(await client.recover(jobId));
|
|
207
|
+
}
|
|
208
|
+
function showQuote(quote, client) {
|
|
209
|
+
const { manifest, service, requirements } = quote;
|
|
210
|
+
const rows = [
|
|
211
|
+
["Provider", `${manifest.provider.name} (${new URL(manifest.baseUrl).host})`],
|
|
212
|
+
["Service", `${service.title ?? service.name}: ${service.description}`],
|
|
213
|
+
["Price", usdc(requirements.amount ?? "0")],
|
|
214
|
+
["Pay to", requirements.payTo ?? "?"],
|
|
215
|
+
["Network", `${requirements.network}${requirements.network === "stellar:testnet" ? " (test money)" : ""}`],
|
|
216
|
+
["Charged", service.charge === "on-success" ? "only if the work succeeds" : "up front, before the work starts"],
|
|
217
|
+
["From", client.address],
|
|
218
|
+
["Method", quote.methodId ?? "none installed for this challenge"],
|
|
219
|
+
];
|
|
220
|
+
if (quote.walletBudget !== undefined)
|
|
221
|
+
rows.push(["Budget", `${usdc(quote.walletBudget)} left in the wallet`]);
|
|
222
|
+
console.log(`\n┌─ Payment approval ${"─".repeat(50)}`);
|
|
223
|
+
for (const [label, value] of rows)
|
|
224
|
+
console.log(`│ ${label.padEnd(9)} ${value}`);
|
|
225
|
+
for (const violation of quote.challengeViolations)
|
|
226
|
+
console.log(`│ ✗ challenge ${violation}`);
|
|
227
|
+
for (const violation of quote.policyViolations)
|
|
228
|
+
console.log(`│ ✗ policy ${violation.field}: ${violation.message}`);
|
|
229
|
+
if (client.payable(quote))
|
|
230
|
+
console.log("│ ✓ The challenge matches the manifest and your spending policy.");
|
|
231
|
+
console.log(`└${"─".repeat(69)}`);
|
|
232
|
+
}
|
|
233
|
+
function showResult({ job, confirmed, unconfirmedReason }) {
|
|
234
|
+
console.log(`\nJob ${job.jobId}: ${job.status}`);
|
|
235
|
+
if (job.payment !== undefined) {
|
|
236
|
+
console.log(`${confirmed ? "✓ Paid" : "⚠ Receipt not confirmed on chain:"} ${usdc(job.payment.amount)} · ${explorerUrl(job.payment.network, job.payment.transaction)}`);
|
|
237
|
+
}
|
|
238
|
+
if (unconfirmedReason !== undefined)
|
|
239
|
+
console.log(` ${unconfirmedReason}`);
|
|
240
|
+
if (job.payment === undefined && job.charged === false) {
|
|
241
|
+
console.log("Not charged.");
|
|
242
|
+
}
|
|
243
|
+
if (job.error !== undefined)
|
|
244
|
+
console.log(`Error: ${job.error.code}${job.error.detail ? `: ${job.error.detail}` : ""}`);
|
|
245
|
+
if (job.output !== undefined)
|
|
246
|
+
console.log(`\n${JSON.stringify(job.output, null, 2)}`);
|
|
247
|
+
if (job.status !== "succeeded" && job.status !== "failed")
|
|
248
|
+
console.log(`Still ${job.status}. Run: stellar-pay recover ${job.jobId}`);
|
|
249
|
+
}
|
|
250
|
+
// ── journal ─────────────────────────────────────────────────────────────────
|
|
251
|
+
async function listJobs() {
|
|
252
|
+
const journal = await Journal.open(fileJournalStorage(files.journal));
|
|
253
|
+
const jobs = new Map();
|
|
254
|
+
for (const entry of journal.entries()) {
|
|
255
|
+
const job = jobs.get(entry.jobId) ?? { service: String(entry.details["service"] ?? "?"), at: entry.at, last: entry.event };
|
|
256
|
+
job.last = entry.event;
|
|
257
|
+
if (entry.event === "sending")
|
|
258
|
+
job.amount = String(entry.details["amount"]);
|
|
259
|
+
jobs.set(entry.jobId, job);
|
|
260
|
+
}
|
|
261
|
+
if (jobs.size === 0)
|
|
262
|
+
return console.log("No jobs yet.");
|
|
263
|
+
for (const [jobId, job] of jobs) {
|
|
264
|
+
console.log(`${job.at.slice(0, 19)} ${jobId} ${job.service.padEnd(16)} ${(job.amount ? usdc(job.amount) : "-").padEnd(12)} ${job.last}`);
|
|
265
|
+
}
|
|
266
|
+
console.log(`\nSpent in the last 24 h: ${usdc(journal.spentSince(new Date(Date.now() - 86400_000)).toString())}`);
|
|
267
|
+
}
|
|
268
|
+
async function journalVerify() {
|
|
269
|
+
const lines = (await fileJournalStorage(files.journal).readLines()).filter((line) => line.trim() !== "");
|
|
270
|
+
const broken = await verifyChain(lines.map((line) => JSON.parse(line)));
|
|
271
|
+
if (broken !== undefined)
|
|
272
|
+
throw new Error(`the journal is broken at entry ${broken}`);
|
|
273
|
+
console.log(`✓ ${lines.length} entries, hash chain intact.`);
|
|
274
|
+
}
|
|
275
|
+
// ── helpers ─────────────────────────────────────────────────────────────────
|
|
276
|
+
async function openClient(dev) {
|
|
277
|
+
const wallet = await readWallet();
|
|
278
|
+
return new PaymentClient({
|
|
279
|
+
signer: localKeySigner(wallet.secret, wallet.network),
|
|
280
|
+
policy: await readPolicy(),
|
|
281
|
+
journal: await Journal.open(fileJournalStorage(files.journal)),
|
|
282
|
+
secrets: fileSecretStore(files.tokens),
|
|
283
|
+
allowLocalhost: dev,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
async function readWallet() {
|
|
287
|
+
if (!(await exists(files.wallet)))
|
|
288
|
+
throw new Error("no wallet yet. Run: stellar-pay wallet create");
|
|
289
|
+
return JSON.parse(await readFile(files.wallet, "utf8"));
|
|
290
|
+
}
|
|
291
|
+
async function readPolicy() {
|
|
292
|
+
if (await exists(files.policy))
|
|
293
|
+
return JSON.parse(await readFile(files.policy, "utf8"));
|
|
294
|
+
return defaultPolicy((await readWallet()).address, NETWORK);
|
|
295
|
+
}
|
|
296
|
+
async function confirm(question) {
|
|
297
|
+
const readline = createInterface({ input: process.stdin, output: process.stdout });
|
|
298
|
+
try {
|
|
299
|
+
return /^y(es)?$/i.test((await readline.question(question)).trim());
|
|
300
|
+
}
|
|
301
|
+
finally {
|
|
302
|
+
readline.close();
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function usdc(baseUnits) {
|
|
306
|
+
const units = BigInt(baseUnits);
|
|
307
|
+
const whole = units / 10000000n;
|
|
308
|
+
const fraction = (units % 10000000n).toString().padStart(7, "0").replace(/0+$/, "");
|
|
309
|
+
return `${whole}${fraction ? `.${fraction.padEnd(2, "0")}` : ".00"} USDC`;
|
|
310
|
+
}
|
|
311
|
+
function toBaseUnits(decimal, allowZero = false) {
|
|
312
|
+
const match = /^(\d+)(?:\.(\d{1,7}))?$/.exec(decimal);
|
|
313
|
+
if (match === null)
|
|
314
|
+
throw new Error(`"${decimal}" is not a USDC amount`);
|
|
315
|
+
const units = BigInt(match[1] + (match[2] ?? "").padEnd(7, "0"));
|
|
316
|
+
if (units === 0n && !allowZero)
|
|
317
|
+
throw new Error("the limit must be above zero");
|
|
318
|
+
return units.toString();
|
|
319
|
+
}
|
|
320
|
+
function short(address) {
|
|
321
|
+
return `${address.slice(0, 6)}…${address.slice(-6)}`;
|
|
322
|
+
}
|
|
323
|
+
function arg(values, index, name) {
|
|
324
|
+
const value = values[index];
|
|
325
|
+
if (value === undefined)
|
|
326
|
+
throw new Error(`missing <${name}>\n\n${HELP}`);
|
|
327
|
+
return value;
|
|
328
|
+
}
|
|
329
|
+
async function exists(path) {
|
|
330
|
+
return readFile(path).then(() => true, () => false);
|
|
331
|
+
}
|
|
332
|
+
main().catch((error) => {
|
|
333
|
+
console.error(`✗ ${error instanceof Error ? error.message : String(error)}`);
|
|
334
|
+
process.exitCode = 1;
|
|
335
|
+
});
|
|
336
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|