@pot-sdk2/pay 0.9.0 → 0.9.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/dist/index.cjs +8 -7
- package/dist/index.d.cts +11 -5
- package/dist/index.d.ts +11 -5
- package/dist/index.js +8 -7
- package/package.json +1 -1
- package/src/policy.ts +20 -10
- package/src/verify-payment.ts +2 -2
- package/tests/pay.test.ts +39 -12
package/dist/index.cjs
CHANGED
|
@@ -47,11 +47,12 @@ function buildAttestationHeaders(result, provider = "thoughtproof.ai") {
|
|
|
47
47
|
|
|
48
48
|
// src/policy.ts
|
|
49
49
|
function resolvePolicy(amount, policy = "tiered") {
|
|
50
|
-
if (policy === "skip") return "skip";
|
|
51
|
-
if (policy === "always") return "sync";
|
|
52
|
-
if (amount < 0.5) return "skip";
|
|
53
|
-
if (amount < 100) return "async";
|
|
54
|
-
return "sync";
|
|
50
|
+
if (policy === "skip") return { mode: "skip", minVerifiers: 0, tiebreakerOnAnyFlag: false };
|
|
51
|
+
if (policy === "always") return { mode: "sync", minVerifiers: 3, tiebreakerOnAnyFlag: false };
|
|
52
|
+
if (amount < 0.5) return { mode: "skip", minVerifiers: 0, tiebreakerOnAnyFlag: false };
|
|
53
|
+
if (amount < 100) return { mode: "async", minVerifiers: 2, tiebreakerOnAnyFlag: false };
|
|
54
|
+
if (amount < 1e3) return { mode: "sync", minVerifiers: 3, tiebreakerOnAnyFlag: false };
|
|
55
|
+
return { mode: "sync-plus", minVerifiers: 3, tiebreakerOnAnyFlag: true };
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
// src/verify-payment.ts
|
|
@@ -82,11 +83,11 @@ async function verifyPayment(reasoningChain, options) {
|
|
|
82
83
|
minConfidence = 0.8,
|
|
83
84
|
attestationProvider = "thoughtproof.ai"
|
|
84
85
|
} = options;
|
|
85
|
-
const
|
|
86
|
+
const policyResult = resolvePolicy(amount, policy);
|
|
86
87
|
const auditId = (0, import_crypto.randomUUID)();
|
|
87
88
|
const txNonce = (0, import_crypto.randomUUID)();
|
|
88
89
|
const chainHash = buildChainHash(reasoningChain, txNonce);
|
|
89
|
-
if (mode === "skip") {
|
|
90
|
+
if (policyResult.mode === "skip") {
|
|
90
91
|
const partialResult2 = {
|
|
91
92
|
verdict: "SKIP",
|
|
92
93
|
confidence: 1,
|
package/dist/index.d.cts
CHANGED
|
@@ -72,12 +72,18 @@ declare function wrapClient<T extends object>(client: T, options: PayWrapOptions
|
|
|
72
72
|
/**
|
|
73
73
|
* Tiered verification policy
|
|
74
74
|
*
|
|
75
|
-
* < $0.50
|
|
76
|
-
*
|
|
77
|
-
*
|
|
75
|
+
* < $0.50 → skip (no verification)
|
|
76
|
+
* $0.50-$100 → async (2 verifiers, background, don't block)
|
|
77
|
+
* $100-$1000 → sync (3 verifiers, block until done)
|
|
78
|
+
* >= $1000 → sync+ (3 verifiers + tiebreaker on ANY flag)
|
|
78
79
|
*/
|
|
79
|
-
type VerificationMode = 'skip' | 'async' | 'sync';
|
|
80
|
-
|
|
80
|
+
type VerificationMode = 'skip' | 'async' | 'sync' | 'sync-plus';
|
|
81
|
+
interface PolicyResult {
|
|
82
|
+
mode: VerificationMode;
|
|
83
|
+
minVerifiers: number;
|
|
84
|
+
tiebreakerOnAnyFlag: boolean;
|
|
85
|
+
}
|
|
86
|
+
declare function resolvePolicy(amount: number, policy?: 'tiered' | 'always' | 'skip'): PolicyResult;
|
|
81
87
|
|
|
82
88
|
/**
|
|
83
89
|
* Generates X-402-Attestation-* headers from a verify result.
|
package/dist/index.d.ts
CHANGED
|
@@ -72,12 +72,18 @@ declare function wrapClient<T extends object>(client: T, options: PayWrapOptions
|
|
|
72
72
|
/**
|
|
73
73
|
* Tiered verification policy
|
|
74
74
|
*
|
|
75
|
-
* < $0.50
|
|
76
|
-
*
|
|
77
|
-
*
|
|
75
|
+
* < $0.50 → skip (no verification)
|
|
76
|
+
* $0.50-$100 → async (2 verifiers, background, don't block)
|
|
77
|
+
* $100-$1000 → sync (3 verifiers, block until done)
|
|
78
|
+
* >= $1000 → sync+ (3 verifiers + tiebreaker on ANY flag)
|
|
78
79
|
*/
|
|
79
|
-
type VerificationMode = 'skip' | 'async' | 'sync';
|
|
80
|
-
|
|
80
|
+
type VerificationMode = 'skip' | 'async' | 'sync' | 'sync-plus';
|
|
81
|
+
interface PolicyResult {
|
|
82
|
+
mode: VerificationMode;
|
|
83
|
+
minVerifiers: number;
|
|
84
|
+
tiebreakerOnAnyFlag: boolean;
|
|
85
|
+
}
|
|
86
|
+
declare function resolvePolicy(amount: number, policy?: 'tiered' | 'always' | 'skip'): PolicyResult;
|
|
81
87
|
|
|
82
88
|
/**
|
|
83
89
|
* Generates X-402-Attestation-* headers from a verify result.
|
package/dist/index.js
CHANGED
|
@@ -18,11 +18,12 @@ function buildAttestationHeaders(result, provider = "thoughtproof.ai") {
|
|
|
18
18
|
|
|
19
19
|
// src/policy.ts
|
|
20
20
|
function resolvePolicy(amount, policy = "tiered") {
|
|
21
|
-
if (policy === "skip") return "skip";
|
|
22
|
-
if (policy === "always") return "sync";
|
|
23
|
-
if (amount < 0.5) return "skip";
|
|
24
|
-
if (amount < 100) return "async";
|
|
25
|
-
return "sync";
|
|
21
|
+
if (policy === "skip") return { mode: "skip", minVerifiers: 0, tiebreakerOnAnyFlag: false };
|
|
22
|
+
if (policy === "always") return { mode: "sync", minVerifiers: 3, tiebreakerOnAnyFlag: false };
|
|
23
|
+
if (amount < 0.5) return { mode: "skip", minVerifiers: 0, tiebreakerOnAnyFlag: false };
|
|
24
|
+
if (amount < 100) return { mode: "async", minVerifiers: 2, tiebreakerOnAnyFlag: false };
|
|
25
|
+
if (amount < 1e3) return { mode: "sync", minVerifiers: 3, tiebreakerOnAnyFlag: false };
|
|
26
|
+
return { mode: "sync-plus", minVerifiers: 3, tiebreakerOnAnyFlag: true };
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
// src/verify-payment.ts
|
|
@@ -53,11 +54,11 @@ async function verifyPayment(reasoningChain, options) {
|
|
|
53
54
|
minConfidence = 0.8,
|
|
54
55
|
attestationProvider = "thoughtproof.ai"
|
|
55
56
|
} = options;
|
|
56
|
-
const
|
|
57
|
+
const policyResult = resolvePolicy(amount, policy);
|
|
57
58
|
const auditId = randomUUID();
|
|
58
59
|
const txNonce = randomUUID();
|
|
59
60
|
const chainHash = buildChainHash(reasoningChain, txNonce);
|
|
60
|
-
if (mode === "skip") {
|
|
61
|
+
if (policyResult.mode === "skip") {
|
|
61
62
|
const partialResult2 = {
|
|
62
63
|
verdict: "SKIP",
|
|
63
64
|
confidence: 1,
|
package/package.json
CHANGED
package/src/policy.ts
CHANGED
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tiered verification policy
|
|
3
3
|
*
|
|
4
|
-
* < $0.50
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* < $0.50 → skip (no verification)
|
|
5
|
+
* $0.50-$100 → async (2 verifiers, background, don't block)
|
|
6
|
+
* $100-$1000 → sync (3 verifiers, block until done)
|
|
7
|
+
* >= $1000 → sync+ (3 verifiers + tiebreaker on ANY flag)
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
export type VerificationMode = 'skip' | 'async' | 'sync';
|
|
10
|
+
export type VerificationMode = 'skip' | 'async' | 'sync' | 'sync-plus';
|
|
11
|
+
|
|
12
|
+
export interface PolicyResult {
|
|
13
|
+
mode: VerificationMode;
|
|
14
|
+
minVerifiers: number;
|
|
15
|
+
tiebreakerOnAnyFlag: boolean;
|
|
16
|
+
}
|
|
10
17
|
|
|
11
18
|
export function resolvePolicy(
|
|
12
19
|
amount: number,
|
|
13
20
|
policy: 'tiered' | 'always' | 'skip' = 'tiered'
|
|
14
|
-
):
|
|
15
|
-
if (policy === 'skip') return 'skip';
|
|
16
|
-
if (policy === 'always') return 'sync';
|
|
21
|
+
): PolicyResult {
|
|
22
|
+
if (policy === 'skip') return { mode: 'skip', minVerifiers: 0, tiebreakerOnAnyFlag: false };
|
|
23
|
+
if (policy === 'always') return { mode: 'sync', minVerifiers: 3, tiebreakerOnAnyFlag: false };
|
|
17
24
|
|
|
18
25
|
// Tiered
|
|
19
|
-
if (amount < 0.50) return 'skip';
|
|
20
|
-
if (amount < 100)
|
|
21
|
-
return 'sync';
|
|
26
|
+
if (amount < 0.50) return { mode: 'skip', minVerifiers: 0, tiebreakerOnAnyFlag: false };
|
|
27
|
+
if (amount < 100) return { mode: 'async', minVerifiers: 2, tiebreakerOnAnyFlag: false };
|
|
28
|
+
if (amount < 1000) return { mode: 'sync', minVerifiers: 3, tiebreakerOnAnyFlag: false };
|
|
29
|
+
|
|
30
|
+
// >= $1000: sync+ — 3 verifiers, but if ANY flags → call 4th as tiebreaker
|
|
31
|
+
return { mode: 'sync-plus', minVerifiers: 3, tiebreakerOnAnyFlag: true };
|
|
22
32
|
}
|
package/src/verify-payment.ts
CHANGED
|
@@ -40,13 +40,13 @@ export async function verifyPayment(
|
|
|
40
40
|
attestationProvider = 'thoughtproof.ai',
|
|
41
41
|
} = options;
|
|
42
42
|
|
|
43
|
-
const
|
|
43
|
+
const policyResult = resolvePolicy(amount, policy);
|
|
44
44
|
const auditId = randomUUID();
|
|
45
45
|
const txNonce = randomUUID();
|
|
46
46
|
const chainHash = buildChainHash(reasoningChain, txNonce);
|
|
47
47
|
|
|
48
48
|
// Skip — no verification for micro-payments
|
|
49
|
-
if (mode === 'skip') {
|
|
49
|
+
if (policyResult.mode === 'skip') {
|
|
50
50
|
const partialResult = {
|
|
51
51
|
verdict: 'SKIP' as const,
|
|
52
52
|
confidence: 1.0,
|
package/tests/pay.test.ts
CHANGED
|
@@ -4,16 +4,43 @@ import assert from 'assert';
|
|
|
4
4
|
|
|
5
5
|
// --- Policy Tests ---
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
assert.strictEqual(
|
|
10
|
-
assert.strictEqual(
|
|
11
|
-
assert.strictEqual(
|
|
12
|
-
|
|
13
|
-
assert.strictEqual(resolvePolicy(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
// Skip tier
|
|
8
|
+
const skip = resolvePolicy(0.10, 'tiered');
|
|
9
|
+
assert.strictEqual(skip.mode, 'skip', 'micro-payment should skip');
|
|
10
|
+
assert.strictEqual(skip.minVerifiers, 0);
|
|
11
|
+
assert.strictEqual(skip.tiebreakerOnAnyFlag, false);
|
|
12
|
+
|
|
13
|
+
assert.strictEqual(resolvePolicy(0.49, 'tiered').mode, 'skip', 'just below threshold');
|
|
14
|
+
|
|
15
|
+
// Async tier (2 verifiers)
|
|
16
|
+
const async2 = resolvePolicy(0.50, 'tiered');
|
|
17
|
+
assert.strictEqual(async2.mode, 'async', '$0.50 should be async');
|
|
18
|
+
assert.strictEqual(async2.minVerifiers, 2);
|
|
19
|
+
|
|
20
|
+
assert.strictEqual(resolvePolicy(50, 'tiered').mode, 'async', '$50 should be async');
|
|
21
|
+
assert.strictEqual(resolvePolicy(99.99, 'tiered').mode, 'async', '$99.99 should be async');
|
|
22
|
+
|
|
23
|
+
// Sync tier (3 verifiers)
|
|
24
|
+
const sync3 = resolvePolicy(100, 'tiered');
|
|
25
|
+
assert.strictEqual(sync3.mode, 'sync', '$100 should be sync');
|
|
26
|
+
assert.strictEqual(sync3.minVerifiers, 3);
|
|
27
|
+
assert.strictEqual(sync3.tiebreakerOnAnyFlag, false);
|
|
28
|
+
|
|
29
|
+
assert.strictEqual(resolvePolicy(500, 'tiered').mode, 'sync', '$500 should be sync');
|
|
30
|
+
assert.strictEqual(resolvePolicy(999.99, 'tiered').mode, 'sync', '$999.99 should be sync');
|
|
31
|
+
|
|
32
|
+
// Sync+ tier (3 verifiers + tiebreaker)
|
|
33
|
+
const syncPlus = resolvePolicy(1000, 'tiered');
|
|
34
|
+
assert.strictEqual(syncPlus.mode, 'sync-plus', '$1000 should be sync-plus');
|
|
35
|
+
assert.strictEqual(syncPlus.minVerifiers, 3);
|
|
36
|
+
assert.strictEqual(syncPlus.tiebreakerOnAnyFlag, true);
|
|
37
|
+
|
|
38
|
+
assert.strictEqual(resolvePolicy(5000, 'tiered').mode, 'sync-plus');
|
|
39
|
+
assert.strictEqual(resolvePolicy(50000, 'tiered').mode, 'sync-plus');
|
|
40
|
+
|
|
41
|
+
// Override policies
|
|
42
|
+
assert.strictEqual(resolvePolicy(0.01, 'always').mode, 'sync', 'always overrides micro');
|
|
43
|
+
assert.strictEqual(resolvePolicy(1000, 'skip').mode, 'skip', 'skip overrides large');
|
|
17
44
|
|
|
18
45
|
console.log('✅ Policy tests passed');
|
|
19
46
|
|
|
@@ -22,7 +49,7 @@ console.log('✅ Policy tests passed');
|
|
|
22
49
|
const mockResult = {
|
|
23
50
|
verdict: 'PASS' as const,
|
|
24
51
|
confidence: 0.94,
|
|
25
|
-
verifiers:
|
|
52
|
+
verifiers: 3,
|
|
26
53
|
chainHash: 'abc123def456',
|
|
27
54
|
auditId: 'test-audit-id',
|
|
28
55
|
latencyMs: 1200,
|
|
@@ -35,7 +62,7 @@ assert.strictEqual(headers['X-402-Attestation-Provider'], 'thoughtproof.ai');
|
|
|
35
62
|
assert.strictEqual(headers['X-402-Attestation-Chain-Hash'], 'sha256:abc123def456');
|
|
36
63
|
assert.strictEqual(headers['X-402-Attestation-Verdict'], 'PASS');
|
|
37
64
|
assert.strictEqual(headers['X-402-Attestation-Confidence'], '0.94');
|
|
38
|
-
assert.strictEqual(headers['X-402-Attestation-Verifiers'], '
|
|
65
|
+
assert.strictEqual(headers['X-402-Attestation-Verifiers'], '3/3');
|
|
39
66
|
assert(headers['X-402-Attestation-Audit-URL'].includes('test-audit-id'));
|
|
40
67
|
assert(headers['X-402-Attestation-Timestamp'].includes('202'));
|
|
41
68
|
|