@tempoxyz/patron 0.0.0-stage → 0.0.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.
@@ -0,0 +1,155 @@
1
+ import { createRequire as __patronCreateRequire } from 'node:module'
2
+ const require = __patronCreateRequire(import.meta.url)
3
+ import {
4
+ statePaths
5
+ } from "./chunk-NLCZ2IHE.js";
6
+
7
+ // src/wallet.ts
8
+ import { Store } from "accounts";
9
+ import { Provider as CliProvider, Storage } from "accounts/cli";
10
+ import { Mppx, tempo as mppxTempo } from "mppx/client";
11
+ import { toHex } from "viem";
12
+ import { privateKeyToAccount } from "viem/accounts";
13
+ import { tempo, tempoModerato } from "viem/chains";
14
+
15
+ // src/browser.ts
16
+ import { spawn } from "node:child_process";
17
+ async function openBrowserUrl(url) {
18
+ const [command, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
19
+ await new Promise((resolve, reject) => {
20
+ const child = spawn(command, args, {
21
+ detached: true,
22
+ stdio: "ignore"
23
+ });
24
+ child.once("error", reject);
25
+ child.once("spawn", () => {
26
+ child.unref();
27
+ resolve();
28
+ });
29
+ });
30
+ }
31
+
32
+ // src/wallet.ts
33
+ var BUDGET_PERIOD_SECONDS = 30 * 24 * 60 * 60;
34
+ async function signIn(settings, options) {
35
+ if (settings.privateKey)
36
+ return { address: privateKeyToAccount(settings.privateKey).address, wallet: "key" };
37
+ const provider = tempoProvider(settings, options.issuer.chainId, options.output);
38
+ await Store.waitForHydration(provider.store);
39
+ const result = await provider.request({
40
+ method: "wallet_connect",
41
+ params: [
42
+ {
43
+ capabilities: {
44
+ authorizeAccessKey: {
45
+ expiry: 0,
46
+ limits: [budgetLimit(options.budgetUnits, options.issuer.currency)]
47
+ }
48
+ }
49
+ }
50
+ ]
51
+ });
52
+ const address = result.accounts[0]?.address;
53
+ if (!address) throw new Error("Tempo Wallet did not authorize Patron.");
54
+ return { address, wallet: "tempo" };
55
+ }
56
+ async function authorizeBudget(settings, options) {
57
+ if (settings.privateKey) return;
58
+ const provider = tempoProvider(settings, options.issuer.chainId, options.output);
59
+ await Store.waitForHydration(provider.store);
60
+ await provider.request({
61
+ method: "wallet_authorizeAccessKey",
62
+ params: [
63
+ { expiry: 0, limits: [budgetLimit(options.budgetUnits, options.issuer.currency)] }
64
+ ]
65
+ });
66
+ }
67
+ async function openWallet(settings, wallet, issuer, maxUnits, output = process.stderr) {
68
+ const policy = {
69
+ currencies: [issuer.currency],
70
+ decimals: 6,
71
+ expectedChainId: issuer.chainId,
72
+ maxAtomicAmount: maxUnits.toString()
73
+ };
74
+ if (wallet === "key") {
75
+ if (!settings.privateKey)
76
+ throw new Error(
77
+ "This Patron install pays with PATRON_PRIVATE_KEY, which is not set."
78
+ );
79
+ const account = privateKeyToAccount(settings.privateKey);
80
+ const payment2 = Mppx.create({
81
+ methods: [mppxTempo.charge({ account, ...policy })],
82
+ polyfill: false
83
+ });
84
+ return {
85
+ address: account.address,
86
+ fetch: payment2.fetch,
87
+ signMessage: (message) => account.signMessage({ message })
88
+ };
89
+ }
90
+ const provider = tempoProvider(settings, issuer.chainId, output);
91
+ await Store.waitForHydration(provider.store);
92
+ const [address] = await provider.request({ method: "eth_accounts" });
93
+ if (!address)
94
+ throw new Error(
95
+ "Tempo Wallet is signed out. Run npx @tempoxyz/patron to sign in again."
96
+ );
97
+ const accessKey = provider.store.getState().accessKeys.find(
98
+ (key) => key.access.toLowerCase() === address.toLowerCase() && key.chainId === issuer.chainId
99
+ );
100
+ const mppParameters = provider.getMppxParameters(
101
+ accessKey ? { accessKey: accessKey.address } : void 0
102
+ );
103
+ const payment = Mppx.create({
104
+ methods: [
105
+ mppxTempo.charge({
106
+ account: provider.getAccount(),
107
+ mode: "pull",
108
+ ...policy,
109
+ ...mppParameters
110
+ })
111
+ ],
112
+ polyfill: false
113
+ });
114
+ return {
115
+ address,
116
+ fetch: payment.fetch,
117
+ signMessage: (message) => provider.request({ method: "personal_sign", params: [toHex(message), address] })
118
+ };
119
+ }
120
+ function budgetLimit(budgetUnits, currency) {
121
+ return {
122
+ limit: toHex(budgetUnits),
123
+ period: BUDGET_PERIOD_SECONDS,
124
+ token: currency
125
+ };
126
+ }
127
+ function tempoProvider(settings, chainId, output) {
128
+ const chain = chainId === tempoModerato.id ? tempoModerato : tempo;
129
+ return CliProvider.create({
130
+ chains: [chain],
131
+ mpp: false,
132
+ name: "Patron",
133
+ open: async (url, prompt) => {
134
+ const code = prompt.userCode.replace(/^(.{4})(.{4})$/, "$1-$2");
135
+ output.write(
136
+ `
137
+ Tempo Wallet sign-in
138
+ Confirm code ${code} in your browser:
139
+ ${url}
140
+
141
+ `
142
+ );
143
+ await openBrowserUrl(url).catch(() => void 0);
144
+ },
145
+ storage: Storage.filesystem({
146
+ key: "patron-tempo",
147
+ path: statePaths(settings.home).wallet
148
+ })
149
+ });
150
+ }
151
+ export {
152
+ authorizeBudget,
153
+ openWallet,
154
+ signIn
155
+ };
package/package.json CHANGED
@@ -1,6 +1,48 @@
1
1
  {
2
- "name": "@tempoxyz/patron",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@tempoxyz/patron",
3
+ "version": "0.0.1",
4
+ "description": "Pay the websites your AI agents read, privately",
5
+ "type": "module",
6
+ "bin": {
7
+ "patron": "dist/bin.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "engines": {
13
+ "node": ">=22"
14
+ },
15
+ "homepage": "https://patron-web.tempo-dev.workers.dev",
16
+ "keywords": [
17
+ "agent",
18
+ "amp",
19
+ "claude-code",
20
+ "codex",
21
+ "cursor",
22
+ "patron",
23
+ "privacy-pass",
24
+ "tempo"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "scripts": {
30
+ "build": "node scripts/build.mjs",
31
+ "check:types": "tsc --project tsconfig.json --noEmit",
32
+ "prepack": "pnpm build",
33
+ "test": "vitest run"
34
+ },
35
+ "devDependencies": {
36
+ "@patron/client": "workspace:*",
37
+ "@patron/protocol": "workspace:*",
38
+ "@types/node": "24.19.2",
39
+ "esbuild": "0.28.2",
40
+ "typescript": "5.9.3",
41
+ "vitest": "4.1.12"
42
+ },
43
+ "dependencies": {
44
+ "accounts": "0.21.0",
45
+ "mppx": "0.15.0",
46
+ "viem": "2.57.12"
47
+ }
48
+ }