tally-sdk 0.1.0 → 0.2.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/.github/workflows/publish.yml +38 -0
- package/dist/src/hook.d.ts +6 -0
- package/dist/src/hook.d.ts.map +1 -0
- package/dist/src/hook.js +37 -0
- package/dist/src/hook.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +22 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/middleware/core.d.ts +15 -0
- package/dist/src/middleware/core.d.ts.map +1 -0
- package/dist/src/middleware/core.js +20 -0
- package/dist/src/middleware/core.js.map +1 -0
- package/dist/src/middleware/express.d.ts +4 -0
- package/dist/src/middleware/express.d.ts.map +1 -0
- package/dist/src/middleware/express.js +26 -0
- package/dist/src/middleware/express.js.map +1 -0
- package/dist/src/store.d.ts +14 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +84 -0
- package/dist/src/store.js.map +1 -0
- package/dist/src/types.d.ts +36 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +19 -5
- package/src/index.ts +2 -0
- package/src/middleware/core.ts +38 -0
- package/src/middleware/express.ts +32 -0
- package/.opencode/commands/opsx-apply.md +0 -152
- package/.opencode/commands/opsx-archive.md +0 -157
- package/.opencode/commands/opsx-explore.md +0 -169
- package/.opencode/commands/opsx-propose.md +0 -104
- package/.opencode/commands/opsx-sync.md +0 -140
- package/.opencode/skills/openspec-apply-change/SKILL.md +0 -159
- package/.opencode/skills/openspec-archive-change/SKILL.md +0 -117
- package/.opencode/skills/openspec-explore/SKILL.md +0 -287
- package/.opencode/skills/openspec-propose/SKILL.md +0 -111
- package/.opencode/skills/openspec-sync-specs/SKILL.md +0 -147
- package/docs/design-hook-store.md +0 -122
- package/docs/plan-hook-store.md +0 -752
- package/test/hook.test.ts +0 -87
- package/test/index.test.ts +0 -36
- package/test/integration.test.ts +0 -44
- package/test/store.test.ts +0 -88
- package/test/types.test.ts +0 -30
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Publish Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
id-token: write
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
publish:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v6
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-node@v6
|
|
20
|
+
with:
|
|
21
|
+
node-version: '24'
|
|
22
|
+
registry-url: 'https://registry.npmjs.org'
|
|
23
|
+
package-manager-cache: false
|
|
24
|
+
|
|
25
|
+
- name: Upgrade npm to v11 (OIDC-capable, runs build scripts)
|
|
26
|
+
run: npm install -g npm@11
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: npm ci
|
|
30
|
+
|
|
31
|
+
- name: Build
|
|
32
|
+
run: npm run build
|
|
33
|
+
|
|
34
|
+
- name: Test
|
|
35
|
+
run: npm test
|
|
36
|
+
|
|
37
|
+
- name: Publish (OIDC trusted publishing)
|
|
38
|
+
run: npm publish --access public
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/hook.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,KAAK,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AAsBD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,KAAK,EACrB,KAAK,EAAE,KAAK,EACZ,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,KAAK,CAiBd"}
|
package/dist/src/hook.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2
|
+
function extractPayload(body, headers, options) {
|
|
3
|
+
const b = (body && typeof body === "object" ? body : {});
|
|
4
|
+
const now = Date.now();
|
|
5
|
+
return {
|
|
6
|
+
id: b.id ?? uuidv4(),
|
|
7
|
+
facilitator: options.facilitator,
|
|
8
|
+
requestId: b.requestId ?? headers.get("x-request-id") ?? "",
|
|
9
|
+
fromAddress: b.fromAddress ?? "",
|
|
10
|
+
toAddress: b.toAddress ?? headers.get("x-payment-address") ?? "",
|
|
11
|
+
amount: b.amount ?? headers.get("x-payment-amount") ?? "0",
|
|
12
|
+
asset: b.asset ?? headers.get("x-payment-asset") ?? "USDC",
|
|
13
|
+
chainId: b.chainId ?? "eip155:1",
|
|
14
|
+
txHash: b.txHash ?? "",
|
|
15
|
+
timestamp: b.timestamp ?? now,
|
|
16
|
+
memo: b.memo ?? undefined,
|
|
17
|
+
metadata: b.metadata ?? undefined,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function createTallyFetch(fetchFn, store, options) {
|
|
21
|
+
return async (input, init) => {
|
|
22
|
+
const response = await fetchFn(input, init);
|
|
23
|
+
if (options && (response.headers.has("x-facilitator") || response.headers.has("x-request-id"))) {
|
|
24
|
+
try {
|
|
25
|
+
const cloned = response.clone();
|
|
26
|
+
const body = await cloned.json();
|
|
27
|
+
const payload = extractPayload(body, cloned.headers, options);
|
|
28
|
+
await store.insert(payload);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// swallow — never break the agent request
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return response;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAOpC,SAAS,cAAc,CAAC,IAAa,EAAE,OAAgB,EAAE,OAAoB;IAC3E,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAA4B,CAAC;IACpF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,OAAO;QACL,EAAE,EAAG,CAAC,CAAC,EAAa,IAAI,MAAM,EAAE;QAChC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,SAAS,EAAG,CAAC,CAAC,SAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE;QACvE,WAAW,EAAG,CAAC,CAAC,WAAsB,IAAI,EAAE;QAC5C,SAAS,EAAG,CAAC,CAAC,SAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE;QAC5E,MAAM,EAAG,CAAC,CAAC,MAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,GAAG;QACtE,KAAK,EAAG,CAAC,CAAC,KAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,MAAM;QACtE,OAAO,EAAG,CAAC,CAAC,OAAkB,IAAI,UAAU;QAC5C,MAAM,EAAG,CAAC,CAAC,MAAiB,IAAI,EAAE;QAClC,SAAS,EAAG,CAAC,CAAC,SAAoB,IAAI,GAAG;QACzC,IAAI,EAAG,CAAC,CAAC,IAAe,IAAI,SAAS;QACrC,QAAQ,EAAE,CAAC,CAAC,QAAmC,IAAI,SAAS;KAC7D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,OAAqB,EACrB,KAAY,EACZ,OAAqB;IAErB,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAE5C,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;YAC/F,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAChC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;gBACjC,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9D,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACP,0CAA0C;YAC5C,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TallyClient, TallyConfig } from "./types.js";
|
|
2
|
+
export type { PaymentPayload, Store, TallyConfig, TallyClient } from "./types.js";
|
|
3
|
+
export { handleIncomingPayment } from "./middleware/core.js";
|
|
4
|
+
export type { IncomingPayment } from "./middleware/core.js";
|
|
5
|
+
export declare function createTally(config: TallyConfig): TallyClient;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAS,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElE,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAsB5D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SqliteStore } from "./store.js";
|
|
2
|
+
import { createTallyFetch } from "./hook.js";
|
|
3
|
+
export { handleIncomingPayment } from "./middleware/core.js";
|
|
4
|
+
export function createTally(config) {
|
|
5
|
+
const store = config.store ?? new SqliteStore("./tally.db");
|
|
6
|
+
const originalFetch = globalThis.fetch;
|
|
7
|
+
const wrappedFetch = createTallyFetch(originalFetch.bind(globalThis), store, { facilitator: config.facilitator });
|
|
8
|
+
return {
|
|
9
|
+
fetch: wrappedFetch,
|
|
10
|
+
wrap() {
|
|
11
|
+
globalThis.fetch = wrappedFetch;
|
|
12
|
+
},
|
|
13
|
+
unwrap() {
|
|
14
|
+
globalThis.fetch = originalFetch;
|
|
15
|
+
},
|
|
16
|
+
store,
|
|
17
|
+
async close() {
|
|
18
|
+
await store.close();
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAI7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,MAAM,KAAK,GAAU,MAAM,CAAC,KAAK,IAAI,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC;IACvC,MAAM,YAAY,GAAG,gBAAgB,CACnC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAC9B,KAAK,EACL,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CACpC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,YAAY;QACnB,IAAI;YACF,UAAU,CAAC,KAAK,GAAG,YAAY,CAAC;QAClC,CAAC;QACD,MAAM;YACJ,UAAU,CAAC,KAAK,GAAG,aAAa,CAAC;QACnC,CAAC;QACD,KAAK;QACL,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PaymentPayload, Store } from "../types.js";
|
|
2
|
+
export interface IncomingPayment {
|
|
3
|
+
facilitator: string;
|
|
4
|
+
requestId?: string;
|
|
5
|
+
fromAddress?: string;
|
|
6
|
+
toAddress?: string;
|
|
7
|
+
amount?: string;
|
|
8
|
+
asset?: string;
|
|
9
|
+
chainId?: string;
|
|
10
|
+
txHash?: string;
|
|
11
|
+
memo?: string;
|
|
12
|
+
metadata?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export declare function handleIncomingPayment(store: Store, payment: IncomingPayment): Promise<PaymentPayload>;
|
|
15
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/middleware/core.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAkBzB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2
|
+
export async function handleIncomingPayment(store, payment) {
|
|
3
|
+
const payload = {
|
|
4
|
+
id: uuidv4(),
|
|
5
|
+
facilitator: payment.facilitator,
|
|
6
|
+
requestId: payment.requestId ?? "",
|
|
7
|
+
fromAddress: payment.fromAddress ?? "",
|
|
8
|
+
toAddress: payment.toAddress ?? "",
|
|
9
|
+
amount: payment.amount ?? "0",
|
|
10
|
+
asset: payment.asset ?? "USDC",
|
|
11
|
+
chainId: payment.chainId ?? "eip155:1",
|
|
12
|
+
txHash: payment.txHash ?? "",
|
|
13
|
+
timestamp: Date.now(),
|
|
14
|
+
memo: payment.memo,
|
|
15
|
+
metadata: payment.metadata,
|
|
16
|
+
};
|
|
17
|
+
await store.insert(payload);
|
|
18
|
+
return payload;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/middleware/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAgBpC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAY,EACZ,OAAwB;IAExB,MAAM,OAAO,GAAmB;QAC9B,EAAE,EAAE,MAAM,EAAE;QACZ,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;QAClC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;QACtC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;QAClC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,GAAG;QAC7B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM;QAC9B,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,UAAU;QACtC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;QAC5B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;IAEF,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from "express";
|
|
2
|
+
import type { Store } from "../types.js";
|
|
3
|
+
export declare function tallyMiddleware(store: Store, facilitator: string): (req: Request, res: Response, next: NextFunction) => void;
|
|
4
|
+
//# sourceMappingURL=express.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../../src/middleware/express.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGzC,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,IACvD,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UA0BxD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { handleIncomingPayment } from "./core.js";
|
|
2
|
+
export function tallyMiddleware(store, facilitator) {
|
|
3
|
+
return (req, res, next) => {
|
|
4
|
+
const originalJson = res.json.bind(res);
|
|
5
|
+
res.json = function (body) {
|
|
6
|
+
if (res.statusCode === 402) {
|
|
7
|
+
const payment = {
|
|
8
|
+
facilitator,
|
|
9
|
+
requestId: req.headers["x-request-id"] ?? undefined,
|
|
10
|
+
fromAddress: body?.fromAddress,
|
|
11
|
+
toAddress: body?.toAddress,
|
|
12
|
+
amount: body?.amount,
|
|
13
|
+
asset: body?.asset,
|
|
14
|
+
chainId: body?.chainId,
|
|
15
|
+
txHash: body?.txHash,
|
|
16
|
+
memo: body?.memo,
|
|
17
|
+
metadata: body?.metadata,
|
|
18
|
+
};
|
|
19
|
+
handleIncomingPayment(store, payment).catch(() => { });
|
|
20
|
+
}
|
|
21
|
+
return originalJson(body);
|
|
22
|
+
};
|
|
23
|
+
next();
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../../src/middleware/express.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAElD,MAAM,UAAU,eAAe,CAAC,KAAY,EAAE,WAAmB;IAC/D,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACzD,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAExC,GAAG,CAAC,IAAI,GAAG,UAAU,IAAa;YAChC,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBAC3B,MAAM,OAAO,GAAG;oBACd,WAAW;oBACX,SAAS,EAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAY,IAAI,SAAS;oBAC/D,WAAW,EAAG,IAAgC,EAAE,WAAiC;oBACjF,SAAS,EAAG,IAAgC,EAAE,SAA+B;oBAC7E,MAAM,EAAG,IAAgC,EAAE,MAA4B;oBACvE,KAAK,EAAG,IAAgC,EAAE,KAA2B;oBACrE,OAAO,EAAG,IAAgC,EAAE,OAA6B;oBACzE,MAAM,EAAG,IAAgC,EAAE,MAA4B;oBACvE,IAAI,EAAG,IAAgC,EAAE,IAA0B;oBACnE,QAAQ,EAAG,IAAgC,EAAE,QAA+C;iBAC7F,CAAC;gBAEF,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACxD,CAAC;YAED,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC,CAAC;QAEF,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PaymentPayload, Store } from "./types.js";
|
|
2
|
+
export declare class SqliteStore implements Store {
|
|
3
|
+
private db;
|
|
4
|
+
constructor(path: string);
|
|
5
|
+
insert(payload: PaymentPayload): Promise<void>;
|
|
6
|
+
list(opts?: {
|
|
7
|
+
facilitator?: string;
|
|
8
|
+
limit?: number;
|
|
9
|
+
offset?: number;
|
|
10
|
+
}): Promise<PaymentPayload[]>;
|
|
11
|
+
get(id: string): Promise<PaymentPayload | null>;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExD,qBAAa,WAAY,YAAW,KAAK;IACvC,OAAO,CAAC,EAAE,CAAoB;gBAElB,IAAI,EAAE,MAAM;IAsBlB,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB9C,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAoBjG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAK/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
export class SqliteStore {
|
|
3
|
+
db;
|
|
4
|
+
constructor(path) {
|
|
5
|
+
this.db = new Database(path);
|
|
6
|
+
this.db.exec(`
|
|
7
|
+
CREATE TABLE IF NOT EXISTS payments (
|
|
8
|
+
id TEXT PRIMARY KEY,
|
|
9
|
+
facilitator TEXT NOT NULL,
|
|
10
|
+
request_id TEXT NOT NULL,
|
|
11
|
+
from_addr TEXT NOT NULL,
|
|
12
|
+
to_addr TEXT NOT NULL,
|
|
13
|
+
amount TEXT NOT NULL,
|
|
14
|
+
asset TEXT NOT NULL DEFAULT 'USDC',
|
|
15
|
+
chain_id TEXT NOT NULL,
|
|
16
|
+
tx_hash TEXT NOT NULL,
|
|
17
|
+
memo TEXT,
|
|
18
|
+
metadata TEXT,
|
|
19
|
+
created_at INTEGER NOT NULL
|
|
20
|
+
);
|
|
21
|
+
CREATE INDEX IF NOT EXISTS idx_payments_facilitator ON payments(facilitator);
|
|
22
|
+
CREATE INDEX IF NOT EXISTS idx_payments_created_at ON payments(created_at);
|
|
23
|
+
`);
|
|
24
|
+
}
|
|
25
|
+
async insert(payload) {
|
|
26
|
+
const stmt = this.db.prepare(`
|
|
27
|
+
INSERT OR IGNORE INTO payments
|
|
28
|
+
(id, facilitator, request_id, from_addr, to_addr, amount, asset, chain_id, tx_hash, memo, metadata, created_at)
|
|
29
|
+
VALUES
|
|
30
|
+
(@id, @facilitator, @requestId, @fromAddress, @toAddress, @amount, @asset, @chainId, @txHash, @memo, @metadata, @createdAt)
|
|
31
|
+
`);
|
|
32
|
+
stmt.run({
|
|
33
|
+
id: payload.id,
|
|
34
|
+
facilitator: payload.facilitator,
|
|
35
|
+
requestId: payload.requestId,
|
|
36
|
+
fromAddress: payload.fromAddress,
|
|
37
|
+
toAddress: payload.toAddress,
|
|
38
|
+
amount: payload.amount,
|
|
39
|
+
asset: payload.asset,
|
|
40
|
+
chainId: payload.chainId,
|
|
41
|
+
txHash: payload.txHash,
|
|
42
|
+
memo: payload.memo ?? null,
|
|
43
|
+
metadata: payload.metadata ? JSON.stringify(payload.metadata) : null,
|
|
44
|
+
createdAt: payload.timestamp,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async list(opts) {
|
|
48
|
+
const conditions = [];
|
|
49
|
+
const params = {};
|
|
50
|
+
if (opts?.facilitator) {
|
|
51
|
+
conditions.push("facilitator = @facilitator");
|
|
52
|
+
params.facilitator = opts.facilitator;
|
|
53
|
+
}
|
|
54
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
55
|
+
const limit = opts?.limit ?? 50;
|
|
56
|
+
const offset = opts?.offset ?? 0;
|
|
57
|
+
const rows = this.db.prepare(`SELECT * FROM payments ${where} ORDER BY created_at DESC LIMIT @limit OFFSET @offset`).all({ ...params, limit, offset });
|
|
58
|
+
return rows.map(rowToPayload);
|
|
59
|
+
}
|
|
60
|
+
async get(id) {
|
|
61
|
+
const row = this.db.prepare("SELECT * FROM payments WHERE id = ?").get(id);
|
|
62
|
+
return row ? rowToPayload(row) : null;
|
|
63
|
+
}
|
|
64
|
+
async close() {
|
|
65
|
+
this.db.close();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function rowToPayload(row) {
|
|
69
|
+
return {
|
|
70
|
+
id: row.id,
|
|
71
|
+
facilitator: row.facilitator,
|
|
72
|
+
requestId: row.request_id,
|
|
73
|
+
fromAddress: row.from_addr,
|
|
74
|
+
toAddress: row.to_addr,
|
|
75
|
+
amount: row.amount,
|
|
76
|
+
asset: row.asset,
|
|
77
|
+
chainId: row.chain_id,
|
|
78
|
+
txHash: row.tx_hash,
|
|
79
|
+
memo: row.memo ?? undefined,
|
|
80
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
|
|
81
|
+
timestamp: row.created_at,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface PaymentPayload {
|
|
2
|
+
id: string;
|
|
3
|
+
facilitator: string;
|
|
4
|
+
requestId: string;
|
|
5
|
+
fromAddress: string;
|
|
6
|
+
toAddress: string;
|
|
7
|
+
amount: string;
|
|
8
|
+
asset: string;
|
|
9
|
+
chainId: string;
|
|
10
|
+
txHash: string;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
memo?: string;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export interface Store {
|
|
16
|
+
insert(payload: PaymentPayload): Promise<void>;
|
|
17
|
+
list(opts?: {
|
|
18
|
+
facilitator?: string;
|
|
19
|
+
limit?: number;
|
|
20
|
+
offset?: number;
|
|
21
|
+
}): Promise<PaymentPayload[]>;
|
|
22
|
+
get(id: string): Promise<PaymentPayload | null>;
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export interface TallyConfig {
|
|
26
|
+
facilitator: string;
|
|
27
|
+
store?: Store;
|
|
28
|
+
}
|
|
29
|
+
export interface TallyClient {
|
|
30
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
31
|
+
wrap(): void;
|
|
32
|
+
unwrap(): void;
|
|
33
|
+
store: Store;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,KAAK;IACpB,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAA;IACjG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IACtE,IAAI,IAAI,IAAI,CAAA;IACZ,MAAM,IAAI,IAAI,CAAA;IACd,KAAK,EAAE,KAAK,CAAA;IACZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tally-sdk",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Accounting, tax, and compliance layer for the agent economy",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
6
|
+
"main": "./dist/src/index.js",
|
|
7
|
+
"types": "./dist/src/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"import": "./dist/index.js",
|
|
11
|
-
"types": "./dist/index.d.ts"
|
|
10
|
+
"import": "./dist/src/index.js",
|
|
11
|
+
"types": "./dist/src/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./middleware/express": {
|
|
14
|
+
"import": "./dist/src/middleware/express.js",
|
|
15
|
+
"types": "./dist/src/middleware/express.d.ts"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"scripts": {
|
|
@@ -23,13 +27,23 @@
|
|
|
23
27
|
"crypto"
|
|
24
28
|
],
|
|
25
29
|
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/Chucks007/tally.git"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public",
|
|
36
|
+
"provenance": false
|
|
37
|
+
},
|
|
26
38
|
"dependencies": {
|
|
27
39
|
"better-sqlite3": "^11.0.0",
|
|
28
40
|
"uuid": "^11.1.1"
|
|
29
41
|
},
|
|
30
42
|
"devDependencies": {
|
|
31
43
|
"@types/better-sqlite3": "^7.6.0",
|
|
44
|
+
"@types/express": "^5.0.6",
|
|
32
45
|
"@types/uuid": "^10.0.0",
|
|
46
|
+
"express": "^5.2.1",
|
|
33
47
|
"typescript": "^5.5.0",
|
|
34
48
|
"vitest": "^2.0.0"
|
|
35
49
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { createTallyFetch } from "./hook.js";
|
|
|
3
3
|
import type { Store, TallyClient, TallyConfig } from "./types.js";
|
|
4
4
|
|
|
5
5
|
export type { PaymentPayload, Store, TallyConfig, TallyClient } from "./types.js";
|
|
6
|
+
export { handleIncomingPayment } from "./middleware/core.js";
|
|
7
|
+
export type { IncomingPayment } from "./middleware/core.js";
|
|
6
8
|
|
|
7
9
|
export function createTally(config: TallyConfig): TallyClient {
|
|
8
10
|
const store: Store = config.store ?? new SqliteStore("./tally.db");
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from "uuid";
|
|
2
|
+
import type { PaymentPayload, Store } from "../types.js";
|
|
3
|
+
|
|
4
|
+
export interface IncomingPayment {
|
|
5
|
+
facilitator: string;
|
|
6
|
+
requestId?: string;
|
|
7
|
+
fromAddress?: string;
|
|
8
|
+
toAddress?: string;
|
|
9
|
+
amount?: string;
|
|
10
|
+
asset?: string;
|
|
11
|
+
chainId?: string;
|
|
12
|
+
txHash?: string;
|
|
13
|
+
memo?: string;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function handleIncomingPayment(
|
|
18
|
+
store: Store,
|
|
19
|
+
payment: IncomingPayment
|
|
20
|
+
): Promise<PaymentPayload> {
|
|
21
|
+
const payload: PaymentPayload = {
|
|
22
|
+
id: uuidv4(),
|
|
23
|
+
facilitator: payment.facilitator,
|
|
24
|
+
requestId: payment.requestId ?? "",
|
|
25
|
+
fromAddress: payment.fromAddress ?? "",
|
|
26
|
+
toAddress: payment.toAddress ?? "",
|
|
27
|
+
amount: payment.amount ?? "0",
|
|
28
|
+
asset: payment.asset ?? "USDC",
|
|
29
|
+
chainId: payment.chainId ?? "eip155:1",
|
|
30
|
+
txHash: payment.txHash ?? "",
|
|
31
|
+
timestamp: Date.now(),
|
|
32
|
+
memo: payment.memo,
|
|
33
|
+
metadata: payment.metadata,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
await store.insert(payload);
|
|
37
|
+
return payload;
|
|
38
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from "express";
|
|
2
|
+
import type { Store } from "../types.js";
|
|
3
|
+
import { handleIncomingPayment } from "./core.js";
|
|
4
|
+
|
|
5
|
+
export function tallyMiddleware(store: Store, facilitator: string) {
|
|
6
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
7
|
+
const originalJson = res.json.bind(res);
|
|
8
|
+
|
|
9
|
+
res.json = function (body: unknown) {
|
|
10
|
+
if (res.statusCode === 402) {
|
|
11
|
+
const payment = {
|
|
12
|
+
facilitator,
|
|
13
|
+
requestId: (req.headers["x-request-id"] as string) ?? undefined,
|
|
14
|
+
fromAddress: (body as Record<string, unknown>)?.fromAddress as string | undefined,
|
|
15
|
+
toAddress: (body as Record<string, unknown>)?.toAddress as string | undefined,
|
|
16
|
+
amount: (body as Record<string, unknown>)?.amount as string | undefined,
|
|
17
|
+
asset: (body as Record<string, unknown>)?.asset as string | undefined,
|
|
18
|
+
chainId: (body as Record<string, unknown>)?.chainId as string | undefined,
|
|
19
|
+
txHash: (body as Record<string, unknown>)?.txHash as string | undefined,
|
|
20
|
+
memo: (body as Record<string, unknown>)?.memo as string | undefined,
|
|
21
|
+
metadata: (body as Record<string, unknown>)?.metadata as Record<string, unknown> | undefined,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
handleIncomingPayment(store, payment).catch(() => {});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return originalJson(body);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
next();
|
|
31
|
+
};
|
|
32
|
+
}
|