@dvmkit/sdk 0.0.0 → 0.1.0-rc.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/NOTICE +2 -0
- package/README.md +38 -2
- package/dist/chunk-27V2ILSR.js +291 -0
- package/dist/chunk-5GFED3GJ.js +955 -0
- package/dist/chunk-6JZIX5WW.js +1155 -0
- package/dist/chunk-7IH5SG2A.js +1038 -0
- package/dist/chunk-AT6V3SY7.js +102 -0
- package/dist/chunk-DCNT4PJS.js +733 -0
- package/dist/chunk-DMNLFNTW.js +135 -0
- package/dist/chunk-FROTD5XQ.js +70 -0
- package/dist/chunk-H25M54MI.js +149 -0
- package/dist/chunk-KQAJVVZT.js +712 -0
- package/dist/chunk-KXWROQGK.js +74 -0
- package/dist/chunk-L4OYF4DQ.js +67 -0
- package/dist/chunk-NTK5DJ6R.js +1256 -0
- package/dist/chunk-RPXHKMYE.js +3808 -0
- package/dist/chunk-S3XAHZQY.js +63 -0
- package/dist/chunk-YG7G4DPZ.js +25 -0
- package/dist/credit-ledger-EDMEZSA2.js +28 -0
- package/dist/index.d.ts +144 -0
- package/dist/index.js +303 -0
- package/dist/job-store-C5n6bhap.d.ts +5090 -0
- package/dist/memory-credit-ledger-7TTZDSRS.js +9 -0
- package/dist/mpp-secret-state-WNAQQ6K4.js +127 -0
- package/dist/mpp-setup-MOBWGTWJ.js +30 -0
- package/dist/postgres-consumed-credential-store-VHBT4KEA.js +72 -0
- package/dist/postgres-job-store-J5F4GUWU.js +7 -0
- package/dist/postgres-kv-store-JFBDP5IP.js +7 -0
- package/dist/postgres-replay-store-UJXRT6VO.js +7 -0
- package/dist/pricing-4CEB34RM.js +48 -0
- package/dist/processed-payment-store-HAA4SFNK.js +11 -0
- package/dist/revenue-reporter-M35KP6V7.js +435 -0
- package/dist/server/index.d.ts +4108 -0
- package/dist/server/index.js +22538 -0
- package/dist/ssrf-BdHsrrIb.d.ts +325 -0
- package/dist/tempo-charge-store-6GJEMNUU.js +130 -0
- package/dist/tempo-session-store-FTEEGZXA.js +467 -0
- package/dist/testing/index.d.ts +135 -0
- package/dist/testing/index.js +151 -0
- package/dist/x402-35VLYFKZ.js +1272 -0
- package/package.json +89 -6
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
withSdkInitLock
|
|
3
|
+
} from "./chunk-S3XAHZQY.js";
|
|
4
|
+
|
|
5
|
+
// src/sdk/server/mpp-secret-state.ts
|
|
6
|
+
var DEFAULT_ROTATION_WINDOW_MS = 5 * 60 * 1e3;
|
|
7
|
+
async function initMppSecretStateTable(db) {
|
|
8
|
+
await withSdkInitLock(db, () => createMppSecretStateTable(db));
|
|
9
|
+
}
|
|
10
|
+
async function createMppSecretStateTable(db) {
|
|
11
|
+
await db.query(`
|
|
12
|
+
CREATE TABLE IF NOT EXISTS mpp_secret_state (
|
|
13
|
+
singleton BOOLEAN PRIMARY KEY DEFAULT TRUE,
|
|
14
|
+
active_secret TEXT NOT NULL,
|
|
15
|
+
previous_secret TEXT,
|
|
16
|
+
previous_expires_at BIGINT,
|
|
17
|
+
rapid_rotation_at BIGINT,
|
|
18
|
+
updated_at BIGINT NOT NULL,
|
|
19
|
+
CONSTRAINT mpp_secret_state_singleton CHECK (singleton)
|
|
20
|
+
);
|
|
21
|
+
`);
|
|
22
|
+
}
|
|
23
|
+
async function loadMppSecretState(db, now = Date.now()) {
|
|
24
|
+
const { rows } = await db.query(
|
|
25
|
+
`SELECT active_secret, previous_secret, previous_expires_at, rapid_rotation_at
|
|
26
|
+
FROM mpp_secret_state
|
|
27
|
+
WHERE singleton = TRUE`
|
|
28
|
+
);
|
|
29
|
+
if (rows.length === 0) return null;
|
|
30
|
+
const row = rows[0];
|
|
31
|
+
const previousExpiresAt = row.previous_expires_at == null ? null : Number(row.previous_expires_at);
|
|
32
|
+
const previous = row.previous_secret != null && previousExpiresAt != null && previousExpiresAt > now ? { secret: row.previous_secret, expiresAtMs: previousExpiresAt } : null;
|
|
33
|
+
const rapidRotationAtRaw = row.rapid_rotation_at == null ? null : Number(row.rapid_rotation_at);
|
|
34
|
+
const rapidRotationAtMs = rapidRotationAtRaw != null && previous != null ? rapidRotationAtRaw : null;
|
|
35
|
+
return {
|
|
36
|
+
active: row.active_secret,
|
|
37
|
+
previous,
|
|
38
|
+
rapidRotationAtMs
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async function applyMppSecretRotation(db, envSecret, rotationWindowMs, now = Date.now()) {
|
|
42
|
+
const client = await db.connect();
|
|
43
|
+
try {
|
|
44
|
+
await client.query("BEGIN");
|
|
45
|
+
const lockedRead = async () => {
|
|
46
|
+
const { rows: rows2 } = await client.query(
|
|
47
|
+
`SELECT active_secret, previous_secret, previous_expires_at, rapid_rotation_at
|
|
48
|
+
FROM mpp_secret_state
|
|
49
|
+
WHERE singleton = TRUE
|
|
50
|
+
FOR UPDATE`
|
|
51
|
+
);
|
|
52
|
+
return rows2;
|
|
53
|
+
};
|
|
54
|
+
let rows = await lockedRead();
|
|
55
|
+
if (rows.length === 0) {
|
|
56
|
+
const inserted = await client.query(
|
|
57
|
+
`INSERT INTO mpp_secret_state
|
|
58
|
+
(singleton, active_secret, previous_secret, previous_expires_at, rapid_rotation_at, updated_at)
|
|
59
|
+
VALUES (TRUE, $1, NULL, NULL, NULL, $2)
|
|
60
|
+
ON CONFLICT (singleton) DO NOTHING`,
|
|
61
|
+
[envSecret, now]
|
|
62
|
+
);
|
|
63
|
+
if ((inserted.rowCount ?? 0) > 0) {
|
|
64
|
+
await client.query("COMMIT");
|
|
65
|
+
return {
|
|
66
|
+
state: { active: envSecret, previous: null, rapidRotationAtMs: null },
|
|
67
|
+
rapidRotation: false
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
rows = await lockedRead();
|
|
71
|
+
if (rows.length === 0) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
"mpp_secret_state: cold-boot insert conflicted but no row is visible afterwards"
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const row = rows[0];
|
|
78
|
+
if (row.active_secret === envSecret) {
|
|
79
|
+
await client.query("COMMIT");
|
|
80
|
+
const previousExpiresAt2 = row.previous_expires_at == null ? null : Number(row.previous_expires_at);
|
|
81
|
+
const previous = row.previous_secret != null && previousExpiresAt2 != null && previousExpiresAt2 > now ? { secret: row.previous_secret, expiresAtMs: previousExpiresAt2 } : null;
|
|
82
|
+
const rapidRotationAtRaw = row.rapid_rotation_at == null ? null : Number(row.rapid_rotation_at);
|
|
83
|
+
const rapidRotationAtMs = rapidRotationAtRaw != null && previous != null ? rapidRotationAtRaw : null;
|
|
84
|
+
return {
|
|
85
|
+
state: { active: envSecret, previous, rapidRotationAtMs },
|
|
86
|
+
rapidRotation: false
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const prevExpiresAtPrior = row.previous_expires_at == null ? null : Number(row.previous_expires_at);
|
|
90
|
+
const rapidRotation = row.previous_secret != null && prevExpiresAtPrior != null && prevExpiresAtPrior > now;
|
|
91
|
+
const previousExpiresAt = now + rotationWindowMs;
|
|
92
|
+
const rapidRotationAt = rapidRotation ? now : null;
|
|
93
|
+
await client.query(
|
|
94
|
+
`UPDATE mpp_secret_state
|
|
95
|
+
SET active_secret = $1,
|
|
96
|
+
previous_secret = $2,
|
|
97
|
+
previous_expires_at = $3,
|
|
98
|
+
rapid_rotation_at = $4,
|
|
99
|
+
updated_at = $5
|
|
100
|
+
WHERE singleton = TRUE`,
|
|
101
|
+
[envSecret, row.active_secret, previousExpiresAt, rapidRotationAt, now]
|
|
102
|
+
);
|
|
103
|
+
await client.query("COMMIT");
|
|
104
|
+
return {
|
|
105
|
+
state: {
|
|
106
|
+
active: envSecret,
|
|
107
|
+
previous: { secret: row.active_secret, expiresAtMs: previousExpiresAt },
|
|
108
|
+
rapidRotationAtMs: rapidRotationAt
|
|
109
|
+
},
|
|
110
|
+
rapidRotation
|
|
111
|
+
};
|
|
112
|
+
} catch (err) {
|
|
113
|
+
try {
|
|
114
|
+
await client.query("ROLLBACK");
|
|
115
|
+
} catch {
|
|
116
|
+
}
|
|
117
|
+
throw err;
|
|
118
|
+
} finally {
|
|
119
|
+
client.release();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export {
|
|
123
|
+
DEFAULT_ROTATION_WINDOW_MS,
|
|
124
|
+
applyMppSecretRotation,
|
|
125
|
+
initMppSecretStateTable,
|
|
126
|
+
loadMppSecretState
|
|
127
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MPPX_HMAC_MISMATCH_REASON,
|
|
3
|
+
TEMPO_SETTLEMENT_IN_FLIGHT,
|
|
4
|
+
TEMPO_SETTLEMENT_LEASE_FIELD,
|
|
5
|
+
TEMPO_SETTLEMENT_LEASE_MS,
|
|
6
|
+
TEMPO_SETTLEMENT_LEASE_OWNER_FIELD,
|
|
7
|
+
TEMPO_USDC_MAINNET,
|
|
8
|
+
_testing,
|
|
9
|
+
advertisedMethods,
|
|
10
|
+
challengeMeta,
|
|
11
|
+
createDualKeyMppxFromOpts,
|
|
12
|
+
createMppFromOpts,
|
|
13
|
+
parseMppMethodsAllowlist,
|
|
14
|
+
wrapMppx
|
|
15
|
+
} from "./chunk-5GFED3GJ.js";
|
|
16
|
+
export {
|
|
17
|
+
MPPX_HMAC_MISMATCH_REASON,
|
|
18
|
+
TEMPO_SETTLEMENT_IN_FLIGHT,
|
|
19
|
+
TEMPO_SETTLEMENT_LEASE_FIELD,
|
|
20
|
+
TEMPO_SETTLEMENT_LEASE_MS,
|
|
21
|
+
TEMPO_SETTLEMENT_LEASE_OWNER_FIELD,
|
|
22
|
+
TEMPO_USDC_MAINNET,
|
|
23
|
+
_testing,
|
|
24
|
+
advertisedMethods,
|
|
25
|
+
challengeMeta,
|
|
26
|
+
createDualKeyMppxFromOpts,
|
|
27
|
+
createMppFromOpts,
|
|
28
|
+
parseMppMethodsAllowlist,
|
|
29
|
+
wrapMppx
|
|
30
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
withSdkInitLock
|
|
3
|
+
} from "./chunk-S3XAHZQY.js";
|
|
4
|
+
|
|
5
|
+
// src/sdk/server/postgres-consumed-credential-store.ts
|
|
6
|
+
var DEFAULT_TABLE_NAME = "consumed_credentials";
|
|
7
|
+
var DEFAULT_GC_SAMPLE_RATE = 0.01;
|
|
8
|
+
var VALID_IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
9
|
+
var PostgresConsumedCredentialStore = class {
|
|
10
|
+
pool;
|
|
11
|
+
tableName;
|
|
12
|
+
gcSampleRate;
|
|
13
|
+
now;
|
|
14
|
+
constructor(pool, opts) {
|
|
15
|
+
const tableName = opts?.tableName ?? DEFAULT_TABLE_NAME;
|
|
16
|
+
if (!VALID_IDENTIFIER.test(tableName)) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`PostgresConsumedCredentialStore: tableName must match ${VALID_IDENTIFIER.source}, got "${tableName}"`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
this.pool = pool;
|
|
22
|
+
this.tableName = tableName;
|
|
23
|
+
this.gcSampleRate = opts?.gcSampleRate ?? DEFAULT_GC_SAMPLE_RATE;
|
|
24
|
+
this.now = opts?.now ?? (() => Date.now());
|
|
25
|
+
}
|
|
26
|
+
/** Run the CREATE TABLE migration. Idempotent — safe to call repeatedly. */
|
|
27
|
+
async init() {
|
|
28
|
+
await withSdkInitLock(this.pool, () => this.createTables());
|
|
29
|
+
}
|
|
30
|
+
/** The boot DDL itself — always runs under {@link withSdkInitLock} (internal-review). */
|
|
31
|
+
async createTables() {
|
|
32
|
+
await this.pool.query(`
|
|
33
|
+
CREATE TABLE IF NOT EXISTS ${this.tableName} (
|
|
34
|
+
realm TEXT NOT NULL,
|
|
35
|
+
challenge_id TEXT NOT NULL,
|
|
36
|
+
expires_at BIGINT NOT NULL,
|
|
37
|
+
PRIMARY KEY (realm, challenge_id)
|
|
38
|
+
);
|
|
39
|
+
CREATE INDEX IF NOT EXISTS ${this.tableName}_expires_at_idx
|
|
40
|
+
ON ${this.tableName} (expires_at);
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
43
|
+
async has(realm, challengeId) {
|
|
44
|
+
const { rowCount } = await this.pool.query(
|
|
45
|
+
`SELECT 1 FROM ${this.tableName}
|
|
46
|
+
WHERE realm = $1 AND challenge_id = $2 AND expires_at > $3`,
|
|
47
|
+
[realm, challengeId, this.now()]
|
|
48
|
+
);
|
|
49
|
+
return (rowCount ?? 0) > 0;
|
|
50
|
+
}
|
|
51
|
+
async mark(realm, challengeId, ttlSeconds) {
|
|
52
|
+
const now = this.now();
|
|
53
|
+
const expiresAt = now + ttlSeconds * 1e3;
|
|
54
|
+
await this.pool.query(
|
|
55
|
+
`INSERT INTO ${this.tableName} (realm, challenge_id, expires_at)
|
|
56
|
+
VALUES ($1, $2, $3)
|
|
57
|
+
ON CONFLICT (realm, challenge_id) DO UPDATE SET expires_at = EXCLUDED.expires_at`,
|
|
58
|
+
[realm, challengeId, expiresAt]
|
|
59
|
+
);
|
|
60
|
+
if (this.gcSampleRate > 0 && Math.random() < this.gcSampleRate) {
|
|
61
|
+
this.gcSweep(now);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
gcSweep(now) {
|
|
65
|
+
this.pool.query(`DELETE FROM ${this.tableName} WHERE expires_at < $1`, [now]).catch((err) => {
|
|
66
|
+
console.error("PostgresConsumedCredentialStore GC sweep failed:", err);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
export {
|
|
71
|
+
PostgresConsumedCredentialStore
|
|
72
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_FX_CURRENCIES,
|
|
3
|
+
DEFAULT_FX_RATE_SOURCE,
|
|
4
|
+
FX_CACHE_TTL_MS,
|
|
5
|
+
FX_RETRY_COUNT,
|
|
6
|
+
FxRateUnavailableError,
|
|
7
|
+
InvalidCurrencyError,
|
|
8
|
+
UnsupportedCurrencyError,
|
|
9
|
+
buildUpfront,
|
|
10
|
+
createFxFetcher,
|
|
11
|
+
fxRateFor,
|
|
12
|
+
resolveFxSourceFromEnv,
|
|
13
|
+
validateCurrency,
|
|
14
|
+
warmFxSnapshot
|
|
15
|
+
} from "./chunk-27V2ILSR.js";
|
|
16
|
+
import {
|
|
17
|
+
InvalidFxRateError,
|
|
18
|
+
InvalidUsdPriceError,
|
|
19
|
+
fiatToSatsCeil,
|
|
20
|
+
formatFiat,
|
|
21
|
+
formatUsd,
|
|
22
|
+
parseUsdPrice,
|
|
23
|
+
roundUsd,
|
|
24
|
+
satsToFiat
|
|
25
|
+
} from "./chunk-AT6V3SY7.js";
|
|
26
|
+
export {
|
|
27
|
+
DEFAULT_FX_CURRENCIES,
|
|
28
|
+
DEFAULT_FX_RATE_SOURCE,
|
|
29
|
+
FX_CACHE_TTL_MS,
|
|
30
|
+
FX_RETRY_COUNT,
|
|
31
|
+
FxRateUnavailableError,
|
|
32
|
+
InvalidCurrencyError,
|
|
33
|
+
InvalidFxRateError,
|
|
34
|
+
InvalidUsdPriceError,
|
|
35
|
+
UnsupportedCurrencyError,
|
|
36
|
+
buildUpfront,
|
|
37
|
+
createFxFetcher,
|
|
38
|
+
fiatToSatsCeil,
|
|
39
|
+
formatFiat,
|
|
40
|
+
formatUsd,
|
|
41
|
+
fxRateFor,
|
|
42
|
+
parseUsdPrice,
|
|
43
|
+
resolveFxSourceFromEnv,
|
|
44
|
+
roundUsd,
|
|
45
|
+
satsToFiat,
|
|
46
|
+
validateCurrency,
|
|
47
|
+
warmFxSnapshot
|
|
48
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MemoryProcessedPaymentStore,
|
|
3
|
+
PostgresProcessedPaymentStore,
|
|
4
|
+
ProcessedPaymentReplayError
|
|
5
|
+
} from "./chunk-DMNLFNTW.js";
|
|
6
|
+
import "./chunk-S3XAHZQY.js";
|
|
7
|
+
export {
|
|
8
|
+
MemoryProcessedPaymentStore,
|
|
9
|
+
PostgresProcessedPaymentStore,
|
|
10
|
+
ProcessedPaymentReplayError
|
|
11
|
+
};
|