@lemmaoracle/x402 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/broadcast/DeployPaymentVerifier.s.sol/10143/run-1775996174982.json +34 -0
- package/broadcast/DeployPaymentVerifier.s.sol/10143/run-1775996423983.json +51 -0
- package/broadcast/DeployPaymentVerifier.s.sol/10143/run-1775996907850.json +51 -0
- package/broadcast/DeployPaymentVerifier.s.sol/10143/run-latest.json +51 -0
- package/cache/DeployPaymentVerifier.s.sol/10143/run-1775996174982.json +7 -0
- package/cache/DeployPaymentVerifier.s.sol/10143/run-1775996423983.json +7 -0
- package/cache/DeployPaymentVerifier.s.sol/10143/run-1775996907850.json +7 -0
- package/cache/DeployPaymentVerifier.s.sol/10143/run-latest.json +7 -0
- package/cache/solidity-files-cache.json +1 -0
- package/circuits/README.md +78 -0
- package/circuits/payment-comprehensive.test.mjs +272 -0
- package/circuits/payment.circom +89 -0
- package/circuits/payment.test.mjs +173 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/proof-generator.d.ts +26 -0
- package/dist/proof-generator.d.ts.map +1 -0
- package/dist/proof-generator.js +154 -0
- package/dist/proof-generator.js.map +1 -0
- package/dist/proof-generator.test.d.ts +7 -0
- package/dist/proof-generator.test.d.ts.map +1 -0
- package/dist/proof-generator.test.js +121 -0
- package/dist/proof-generator.test.js.map +1 -0
- package/dist/transaction-watcher.d.ts +42 -0
- package/dist/transaction-watcher.d.ts.map +1 -0
- package/dist/transaction-watcher.js +88 -0
- package/dist/transaction-watcher.js.map +1 -0
- package/dist/transaction-watcher.test.d.ts +7 -0
- package/dist/transaction-watcher.test.d.ts.map +1 -0
- package/dist/transaction-watcher.test.js +111 -0
- package/dist/transaction-watcher.test.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/foundry.lock +11 -0
- package/foundry.toml +16 -0
- package/lib/forge-std/.gitattributes +1 -0
- package/lib/forge-std/.github/CODEOWNERS +1 -0
- package/lib/forge-std/.github/dependabot.yml +6 -0
- package/lib/forge-std/.github/workflows/ci.yml +161 -0
- package/lib/forge-std/.github/workflows/sync.yml +36 -0
- package/lib/forge-std/CONTRIBUTING.md +193 -0
- package/lib/forge-std/LICENSE-APACHE +203 -0
- package/lib/forge-std/LICENSE-MIT +25 -0
- package/lib/forge-std/README.md +314 -0
- package/lib/forge-std/RELEASE_CHECKLIST.md +12 -0
- package/lib/forge-std/foundry.toml +18 -0
- package/lib/forge-std/package.json +16 -0
- package/lib/forge-std/scripts/vm.py +636 -0
- package/lib/forge-std/src/Base.sol +48 -0
- package/lib/forge-std/src/Config.sol +60 -0
- package/lib/forge-std/src/LibVariable.sol +477 -0
- package/lib/forge-std/src/Script.sol +28 -0
- package/lib/forge-std/src/StdAssertions.sol +1300 -0
- package/lib/forge-std/src/StdChains.sol +303 -0
- package/lib/forge-std/src/StdCheats.sol +825 -0
- package/lib/forge-std/src/StdConfig.sol +632 -0
- package/lib/forge-std/src/StdConstants.sol +30 -0
- package/lib/forge-std/src/StdError.sol +15 -0
- package/lib/forge-std/src/StdInvariant.sol +161 -0
- package/lib/forge-std/src/StdJson.sol +275 -0
- package/lib/forge-std/src/StdMath.sol +47 -0
- package/lib/forge-std/src/StdStorage.sol +476 -0
- package/lib/forge-std/src/StdStyle.sol +333 -0
- package/lib/forge-std/src/StdToml.sol +275 -0
- package/lib/forge-std/src/StdUtils.sol +200 -0
- package/lib/forge-std/src/Test.sol +32 -0
- package/lib/forge-std/src/Vm.sol +2533 -0
- package/lib/forge-std/src/console.sol +1551 -0
- package/lib/forge-std/src/console2.sol +4 -0
- package/lib/forge-std/src/interfaces/IERC1155.sol +105 -0
- package/lib/forge-std/src/interfaces/IERC165.sol +12 -0
- package/lib/forge-std/src/interfaces/IERC20.sol +43 -0
- package/lib/forge-std/src/interfaces/IERC4626.sol +190 -0
- package/lib/forge-std/src/interfaces/IERC6909.sol +72 -0
- package/lib/forge-std/src/interfaces/IERC721.sol +164 -0
- package/lib/forge-std/src/interfaces/IERC7540.sol +145 -0
- package/lib/forge-std/src/interfaces/IERC7575.sol +241 -0
- package/lib/forge-std/src/interfaces/IMulticall3.sol +68 -0
- package/lib/forge-std/src/safeconsole.sol +13248 -0
- package/lib/forge-std/test/CommonBase.t.sol +44 -0
- package/lib/forge-std/test/Config.t.sol +381 -0
- package/lib/forge-std/test/LibVariable.t.sol +452 -0
- package/lib/forge-std/test/StdAssertions.t.sol +141 -0
- package/lib/forge-std/test/StdChains.t.sol +227 -0
- package/lib/forge-std/test/StdCheats.t.sol +638 -0
- package/lib/forge-std/test/StdConstants.t.sol +38 -0
- package/lib/forge-std/test/StdError.t.sol +119 -0
- package/lib/forge-std/test/StdJson.t.sol +49 -0
- package/lib/forge-std/test/StdMath.t.sol +202 -0
- package/lib/forge-std/test/StdStorage.t.sol +532 -0
- package/lib/forge-std/test/StdStyle.t.sol +110 -0
- package/lib/forge-std/test/StdToml.t.sol +49 -0
- package/lib/forge-std/test/StdUtils.t.sol +342 -0
- package/lib/forge-std/test/Vm.t.sol +18 -0
- package/lib/forge-std/test/compilation/CompilationScript.sol +8 -0
- package/lib/forge-std/test/compilation/CompilationScriptBase.sol +8 -0
- package/lib/forge-std/test/compilation/CompilationTest.sol +8 -0
- package/lib/forge-std/test/compilation/CompilationTestBase.sol +8 -0
- package/lib/forge-std/test/fixtures/broadcast.log.json +187 -0
- package/lib/forge-std/test/fixtures/config.toml +81 -0
- package/lib/forge-std/test/fixtures/test.json +8 -0
- package/lib/forge-std/test/fixtures/test.toml +6 -0
- package/package.json +55 -0
- package/package.json.backup +55 -0
- package/scripts/DeployPaymentVerifier.s.sol +18 -0
- package/scripts/build.sh +61 -0
- package/scripts/deploy.sh +65 -0
- package/scripts/fix-verifier.mjs +64 -0
- package/scripts/register-circuit.ts +213 -0
- package/scripts/test-with-circuit.mjs +88 -0
- package/src/index.ts +115 -0
- package/src/proof-generator.test.ts +139 -0
- package/src/proof-generator.ts +220 -0
- package/src/transaction-watcher.test.ts +153 -0
- package/src/transaction-watcher.ts +154 -0
- package/src/types.ts +110 -0
- package/tsconfig.json +14 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +18 -0
- package/workers/x402-facilitator/src/index.ts +582 -0
- package/workers/x402-facilitator/src/x402-env.d.ts +25 -0
- package/workers/x402-facilitator/wrangler.toml +19 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for x402 transaction watcher.
|
|
3
|
+
*
|
|
4
|
+
* Test files are exempt from FP rules.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, vi } from "vitest";
|
|
8
|
+
import {
|
|
9
|
+
createTransactionWatcher,
|
|
10
|
+
isValidPayment,
|
|
11
|
+
extractPaymentDetails,
|
|
12
|
+
} from "./transaction-watcher.js";
|
|
13
|
+
import type { Config } from "./types.js";
|
|
14
|
+
|
|
15
|
+
const mockConfig: Config = {
|
|
16
|
+
payToAddress: "0x2222222222222222222222222222222222222222" as `0x${string}`,
|
|
17
|
+
network: "eip155:84532",
|
|
18
|
+
price: "$0.001",
|
|
19
|
+
ethereumRpcUrl: "https://sepolia.base.org",
|
|
20
|
+
chainId: 84532,
|
|
21
|
+
lemmaApiBase: "https://workers.lemma.workers.dev",
|
|
22
|
+
circuitId: "x402-payment-v1",
|
|
23
|
+
minAmount: 1000n,
|
|
24
|
+
requiredConfirmations: 6,
|
|
25
|
+
maxProofAge: 3600,
|
|
26
|
+
ipfsGateway: "https://ipfs.io/ipfs/",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const mockTx = {
|
|
30
|
+
hash: "0xabc123",
|
|
31
|
+
from: "0x1111111111111111111111111111111111111111",
|
|
32
|
+
to: "0x2222222222222222222222222222222222222222",
|
|
33
|
+
value: 2000n,
|
|
34
|
+
blockNumber: 1000n,
|
|
35
|
+
blockTimestamp: 1712000000n,
|
|
36
|
+
gasUsed: 21000n,
|
|
37
|
+
effectiveGasPrice: 1000000000n,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const mockReceipt = {
|
|
41
|
+
status: "success" as const,
|
|
42
|
+
blockNumber: 1000n,
|
|
43
|
+
confirmations: 6,
|
|
44
|
+
gasUsed: 21000n,
|
|
45
|
+
effectiveGasPrice: 1000000000n,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
describe("Transaction Watcher", () => {
|
|
49
|
+
it("should create a watcher", () => {
|
|
50
|
+
const watcher = createTransactionWatcher(mockConfig, {});
|
|
51
|
+
|
|
52
|
+
expect(watcher).toBeDefined();
|
|
53
|
+
expect(typeof watcher.start).toBe("function");
|
|
54
|
+
expect(typeof watcher.stop).toBe("function");
|
|
55
|
+
expect(typeof watcher.onPaymentDetected).toBe("function");
|
|
56
|
+
expect(typeof watcher.getState).toBe("function");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("should register payment detected callbacks", async () => {
|
|
60
|
+
const watcher = createTransactionWatcher(mockConfig, {});
|
|
61
|
+
const callback = vi.fn();
|
|
62
|
+
|
|
63
|
+
// Callbacks return Promises
|
|
64
|
+
const promise = watcher.onPaymentDetected(callback);
|
|
65
|
+
|
|
66
|
+
expect(promise).toBeInstanceOf(Promise);
|
|
67
|
+
await promise;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("should return watcher state", () => {
|
|
71
|
+
const watcher = createTransactionWatcher(mockConfig, {});
|
|
72
|
+
const state = watcher.getState();
|
|
73
|
+
|
|
74
|
+
expect(state.isRunning).toBe(false);
|
|
75
|
+
expect(Array.isArray(state.detectedPayments)).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("isValidPayment", () => {
|
|
80
|
+
it("should validate a correct payment", () => {
|
|
81
|
+
const currentBlockNumber = 1010n; // Sufficient confirmations (10 confirmations)
|
|
82
|
+
const result = isValidPayment(mockTx as any, mockReceipt as any, mockConfig, currentBlockNumber);
|
|
83
|
+
|
|
84
|
+
expect(result).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("should reject payment to wrong recipient", () => {
|
|
88
|
+
const badTx = { ...mockTx, to: "0x3333333333333333333333333333333333333333" };
|
|
89
|
+
const currentBlockNumber = 1010n;
|
|
90
|
+
|
|
91
|
+
const result = isValidPayment(badTx as any, mockReceipt as any, mockConfig, currentBlockNumber);
|
|
92
|
+
|
|
93
|
+
expect(result).toBe(false);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("should reject payment below minimum amount", () => {
|
|
97
|
+
const lowTx = { ...mockTx, value: 500n };
|
|
98
|
+
const currentBlockNumber = 1010n;
|
|
99
|
+
|
|
100
|
+
const result = isValidPayment(lowTx as any, mockReceipt as any, mockConfig, currentBlockNumber);
|
|
101
|
+
|
|
102
|
+
expect(result).toBe(false);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("should reject failed transaction", () => {
|
|
106
|
+
const failedReceipt = { ...mockReceipt, status: "reverted" as const };
|
|
107
|
+
const currentBlockNumber = 1010n;
|
|
108
|
+
|
|
109
|
+
const result = isValidPayment(mockTx as any, failedReceipt as any, mockConfig, currentBlockNumber);
|
|
110
|
+
|
|
111
|
+
expect(result).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("should reject payment with insufficient confirmations", () => {
|
|
115
|
+
const currentBlockNumber = 1002n; // Only 2 confirmations (1002 - 1000 = 2)
|
|
116
|
+
const result = isValidPayment(mockTx as any, mockReceipt as any, mockConfig, currentBlockNumber);
|
|
117
|
+
|
|
118
|
+
expect(result).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe("extractPaymentDetails", () => {
|
|
123
|
+
it("should extract payment details from transaction and receipt", () => {
|
|
124
|
+
const currentBlockNumber = 1010n;
|
|
125
|
+
|
|
126
|
+
const details = extractPaymentDetails(
|
|
127
|
+
mockTx as any,
|
|
128
|
+
mockReceipt as any,
|
|
129
|
+
currentBlockNumber,
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
expect(details.txHash).toBe("0xabc123");
|
|
133
|
+
expect(details.from).toBe("0x1111111111111111111111111111111111111111");
|
|
134
|
+
expect(details.to).toBe("0x2222222222222222222222222222222222222222");
|
|
135
|
+
expect(details.amount).toBe(2000n);
|
|
136
|
+
expect(details.timestamp).toBe(1712000000); // Retrieved from blockTimestamp
|
|
137
|
+
expect(details.blockNumber).toBe(1000n);
|
|
138
|
+
expect(details.confirmations).toBe(10);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("should handle missing blockTimestamp", () => {
|
|
142
|
+
const txNoTimestamp = { ...mockTx, blockTimestamp: undefined };
|
|
143
|
+
const currentBlockNumber = 1010n;
|
|
144
|
+
|
|
145
|
+
const details = extractPaymentDetails(
|
|
146
|
+
txNoTimestamp as any,
|
|
147
|
+
mockReceipt as any,
|
|
148
|
+
currentBlockNumber,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
expect(details.timestamp).toBe(0);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X402 Transaction Watcher
|
|
3
|
+
*
|
|
4
|
+
* Monitors the blockchain for x402 payment transactions to the configured
|
|
5
|
+
* recipient address and triggers proof generation when payments are detected.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
Transaction as ViemTransaction,
|
|
10
|
+
TransactionReceipt,
|
|
11
|
+
} from "viem";
|
|
12
|
+
import * as R from "ramda";
|
|
13
|
+
import type { Config, Transaction } from "./types.js";
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Types
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/** Callback invoked when a valid payment is detected */
|
|
20
|
+
type PaymentDetectedCallback = (
|
|
21
|
+
payment: Transaction,
|
|
22
|
+
) => Promise<void>;
|
|
23
|
+
|
|
24
|
+
/** State of the transaction watcher */
|
|
25
|
+
type WatcherState = Readonly<{
|
|
26
|
+
isRunning: boolean;
|
|
27
|
+
lastCheckedBlock: bigint;
|
|
28
|
+
detectedPayments: ReadonlyArray<PaymentDetectedCallback>;
|
|
29
|
+
}>;
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Watcher Implementation
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
const initialState: WatcherState = {
|
|
36
|
+
isRunning: false,
|
|
37
|
+
lastCheckedBlock: 0n,
|
|
38
|
+
detectedPayments: [],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a transaction watcher that monitors for payments to the configured address.
|
|
43
|
+
*
|
|
44
|
+
* Uses an immutable state cell (single-element tuple) as a controlled mutable reference.
|
|
45
|
+
*/
|
|
46
|
+
const createTransactionWatcher = (
|
|
47
|
+
_config: Config,
|
|
48
|
+
_publicClient: unknown,
|
|
49
|
+
): Readonly<{
|
|
50
|
+
start: (_?: undefined) => Promise<void>;
|
|
51
|
+
stop: (_?: undefined) => void;
|
|
52
|
+
onPaymentDetected: (callback: PaymentDetectedCallback) => Promise<void>;
|
|
53
|
+
getState: (_?: undefined) => WatcherState;
|
|
54
|
+
}> => {
|
|
55
|
+
const stateCell = { current: initialState };
|
|
56
|
+
|
|
57
|
+
const start = (_?: undefined): Promise<void> => {
|
|
58
|
+
// eslint-disable-next-line functional/no-expression-statements, functional/immutable-data
|
|
59
|
+
stateCell.current = {
|
|
60
|
+
...stateCell.current,
|
|
61
|
+
isRunning: true,
|
|
62
|
+
lastCheckedBlock: 0n,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return Promise.resolve();
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const stop = (_?: undefined): void => {
|
|
69
|
+
// eslint-disable-next-line functional/no-expression-statements, functional/immutable-data
|
|
70
|
+
stateCell.current = R.assoc("isRunning", false, stateCell.current);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const onPaymentDetected = (
|
|
74
|
+
callback: PaymentDetectedCallback,
|
|
75
|
+
): Promise<void> => {
|
|
76
|
+
// eslint-disable-next-line functional/no-expression-statements, functional/immutable-data
|
|
77
|
+
stateCell.current = {
|
|
78
|
+
...stateCell.current,
|
|
79
|
+
detectedPayments: R.append(callback, stateCell.current.detectedPayments),
|
|
80
|
+
};
|
|
81
|
+
return Promise.resolve();
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const getState = (_?: undefined): WatcherState => stateCell.current;
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
start,
|
|
88
|
+
stop,
|
|
89
|
+
onPaymentDetected,
|
|
90
|
+
getState,
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Utility Functions
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Validate that a transaction is a valid x402 payment:
|
|
100
|
+
* - Transaction was successful
|
|
101
|
+
* - Sent to the correct recipient
|
|
102
|
+
* - Amount meets the minimum requirement
|
|
103
|
+
* - Has sufficient confirmations
|
|
104
|
+
*/
|
|
105
|
+
const isValidPayment = (
|
|
106
|
+
tx: ViemTransaction,
|
|
107
|
+
receipt: TransactionReceipt,
|
|
108
|
+
config: Config,
|
|
109
|
+
currentBlockNumber: bigint = 0n,
|
|
110
|
+
): boolean =>
|
|
111
|
+
R.allPass([
|
|
112
|
+
R.always(tx.to === config.payToAddress),
|
|
113
|
+
R.always(tx.value >= config.minAmount),
|
|
114
|
+
R.always(receipt.status === "success"),
|
|
115
|
+
R.always(
|
|
116
|
+
currentBlockNumber > 0n
|
|
117
|
+
? Number(currentBlockNumber - receipt.blockNumber) >= config.requiredConfirmations
|
|
118
|
+
: true,
|
|
119
|
+
),
|
|
120
|
+
])();
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Extract payment details from transaction and receipt.
|
|
124
|
+
*/
|
|
125
|
+
const extractPaymentDetails = (
|
|
126
|
+
tx: ViemTransaction,
|
|
127
|
+
receipt: TransactionReceipt,
|
|
128
|
+
currentBlockNumber: bigint,
|
|
129
|
+
): Transaction => {
|
|
130
|
+
const txRecord = tx as unknown as Readonly<Record<string, unknown>>;
|
|
131
|
+
const rawTimestamp = txRecord["blockTimestamp"];
|
|
132
|
+
const timestamp = typeof rawTimestamp === "bigint" ? Number(rawTimestamp) : 0;
|
|
133
|
+
|
|
134
|
+
return R.always({
|
|
135
|
+
txHash: tx.hash,
|
|
136
|
+
from: tx.from,
|
|
137
|
+
to: tx.to ?? ("0x" as `0x${string}`),
|
|
138
|
+
amount: tx.value,
|
|
139
|
+
timestamp,
|
|
140
|
+
blockNumber: receipt.blockNumber,
|
|
141
|
+
confirmations: Number(currentBlockNumber - receipt.blockNumber),
|
|
142
|
+
})();
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export type {
|
|
146
|
+
PaymentDetectedCallback,
|
|
147
|
+
WatcherState,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export {
|
|
151
|
+
createTransactionWatcher,
|
|
152
|
+
isValidPayment,
|
|
153
|
+
extractPaymentDetails,
|
|
154
|
+
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/** Configuration for payment facilitator */
|
|
2
|
+
type Config = Readonly<{
|
|
3
|
+
/** x402 facilitator URL (for HTTPFacilitatorClient compatibility) */
|
|
4
|
+
facilitatorUrl?: string;
|
|
5
|
+
|
|
6
|
+
/** Address to receive payments */
|
|
7
|
+
payToAddress: `0x${string}`;
|
|
8
|
+
|
|
9
|
+
/** Network identifier (e.g., "eip155:84532" for Base Sepolia) */
|
|
10
|
+
network: string;
|
|
11
|
+
|
|
12
|
+
/** Price for accessing verified attributes (e.g., "$0.001") */
|
|
13
|
+
price: string;
|
|
14
|
+
|
|
15
|
+
/** Ethereum RPC URL for transaction monitoring */
|
|
16
|
+
ethereumRpcUrl: string;
|
|
17
|
+
|
|
18
|
+
/** Chain ID for the network */
|
|
19
|
+
chainId: number;
|
|
20
|
+
|
|
21
|
+
/** Lemma API base URL */
|
|
22
|
+
lemmaApiBase: string;
|
|
23
|
+
|
|
24
|
+
/** Lemma API key (if required) */
|
|
25
|
+
lemmaApiKey?: string;
|
|
26
|
+
|
|
27
|
+
/** Circuit ID for the payment proof */
|
|
28
|
+
circuitId: string;
|
|
29
|
+
|
|
30
|
+
/** Minimum amount in USDC smallest unit (6 decimals) */
|
|
31
|
+
minAmount: bigint;
|
|
32
|
+
|
|
33
|
+
/** Number of block confirmations before considering payment valid */
|
|
34
|
+
requiredConfirmations: number;
|
|
35
|
+
|
|
36
|
+
/** Maximum age of payment proof in seconds */
|
|
37
|
+
maxProofAge: number;
|
|
38
|
+
|
|
39
|
+
/** IPFS gateway URL for fetching circuit artifacts */
|
|
40
|
+
ipfsGateway?: string;
|
|
41
|
+
}>;
|
|
42
|
+
|
|
43
|
+
/** Parsed transaction details */
|
|
44
|
+
type Transaction = Readonly<{
|
|
45
|
+
/** Transaction hash */
|
|
46
|
+
txHash: `0x${string}`;
|
|
47
|
+
|
|
48
|
+
/** Sender address */
|
|
49
|
+
from: `0x${string}`;
|
|
50
|
+
|
|
51
|
+
/** Recipient address */
|
|
52
|
+
to: `0x${string}`;
|
|
53
|
+
|
|
54
|
+
/** Amount in smallest token unit */
|
|
55
|
+
amount: bigint;
|
|
56
|
+
|
|
57
|
+
/** Block timestamp */
|
|
58
|
+
timestamp: number;
|
|
59
|
+
|
|
60
|
+
/** Block number */
|
|
61
|
+
blockNumber: bigint;
|
|
62
|
+
|
|
63
|
+
/** Number of confirmations */
|
|
64
|
+
confirmations: number;
|
|
65
|
+
}>;
|
|
66
|
+
|
|
67
|
+
/** Generated proof with inputs for Lemma API */
|
|
68
|
+
type Proof = Readonly<{
|
|
69
|
+
/** ZK proof data (base64 encoded) */
|
|
70
|
+
proof: string;
|
|
71
|
+
|
|
72
|
+
/** Public inputs for the circuit */
|
|
73
|
+
inputs: ReadonlyArray<string>;
|
|
74
|
+
|
|
75
|
+
/** Circuit ID used */
|
|
76
|
+
circuitId: string;
|
|
77
|
+
|
|
78
|
+
/** Timestamp when proof was generated */
|
|
79
|
+
generatedAt: number;
|
|
80
|
+
}>;
|
|
81
|
+
|
|
82
|
+
/** Result of proof generation */
|
|
83
|
+
type ProofResult = Readonly<{
|
|
84
|
+
/** Transaction */
|
|
85
|
+
payment: Transaction;
|
|
86
|
+
|
|
87
|
+
/** Generated proof */
|
|
88
|
+
proof: Proof;
|
|
89
|
+
}>;
|
|
90
|
+
|
|
91
|
+
/** Disclosure condition for Lemma API query */
|
|
92
|
+
type DisclosureCondition = Readonly<{
|
|
93
|
+
circuitId: string;
|
|
94
|
+
}>;
|
|
95
|
+
|
|
96
|
+
/** Disclosure object to send with query */
|
|
97
|
+
type Disclosure = Readonly<{
|
|
98
|
+
condition?: DisclosureCondition;
|
|
99
|
+
proof: string;
|
|
100
|
+
inputs: ReadonlyArray<string>;
|
|
101
|
+
}>;
|
|
102
|
+
|
|
103
|
+
export type {
|
|
104
|
+
Config,
|
|
105
|
+
Transaction,
|
|
106
|
+
Proof,
|
|
107
|
+
ProofResult,
|
|
108
|
+
Disclosure,
|
|
109
|
+
DisclosureCondition,
|
|
110
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"resolveJsonModule": true
|
|
7
|
+
},
|
|
8
|
+
"include": ["src/**/*"],
|
|
9
|
+
"exclude": ["node_modules", "dist", "workers"],
|
|
10
|
+
"references": [
|
|
11
|
+
{ "path": "../spec" },
|
|
12
|
+
{ "path": "../sdk" }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/index.ts","./src/proof-generator.test.ts","./src/proof-generator.ts","./src/transaction-watcher.test.ts","./src/transaction-watcher.ts","./src/types.ts"],"version":"5.8.3"}
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
exclude: [
|
|
6
|
+
'**/node_modules/**',
|
|
7
|
+
'**/dist/**',
|
|
8
|
+
'**/build/**',
|
|
9
|
+
'**/*.test.mjs', // Exclude circuit test files
|
|
10
|
+
'**/*.spec.mjs',
|
|
11
|
+
'**/circuits/**/*.mjs', // Exclude all .mjs files in circuits directory
|
|
12
|
+
],
|
|
13
|
+
include: [
|
|
14
|
+
'**/*.test.ts',
|
|
15
|
+
'**/*.spec.ts',
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
});
|