@antseed/node 0.1.0 → 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/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/seller-provider.d.ts +13 -1
- package/dist/interfaces/seller-provider.d.ts.map +1 -1
- package/dist/node.d.ts +13 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +123 -15
- package/dist/node.js.map +1 -1
- package/dist/proxy/proxy-mux.d.ts +3 -1
- package/dist/proxy/proxy-mux.d.ts.map +1 -1
- package/dist/proxy/proxy-mux.js +9 -5
- package/dist/proxy/proxy-mux.js.map +1 -1
- package/dist/types/http.d.ts +1 -0
- package/dist/types/http.d.ts.map +1 -1
- package/dist/types/http.js +1 -1
- package/dist/types/http.js.map +1 -1
- package/package.json +14 -10
- package/contracts/AntseedEscrow.sol +0 -310
- package/contracts/MockUSDC.sol +0 -64
- package/contracts/README.md +0 -102
- package/src/config/encryption.test.ts +0 -49
- package/src/config/encryption.ts +0 -53
- package/src/config/plugin-config-manager.test.ts +0 -92
- package/src/config/plugin-config-manager.ts +0 -153
- package/src/config/plugin-loader.ts +0 -90
- package/src/discovery/announcer.ts +0 -169
- package/src/discovery/bootstrap.ts +0 -57
- package/src/discovery/default-metadata-resolver.ts +0 -18
- package/src/discovery/dht-health.ts +0 -136
- package/src/discovery/dht-node.ts +0 -191
- package/src/discovery/http-metadata-resolver.ts +0 -47
- package/src/discovery/index.ts +0 -15
- package/src/discovery/metadata-codec.ts +0 -453
- package/src/discovery/metadata-resolver.ts +0 -7
- package/src/discovery/metadata-server.ts +0 -73
- package/src/discovery/metadata-validator.ts +0 -172
- package/src/discovery/peer-lookup.ts +0 -122
- package/src/discovery/peer-metadata.ts +0 -34
- package/src/discovery/peer-selector.ts +0 -134
- package/src/discovery/profile-manager.ts +0 -131
- package/src/discovery/profile-search.ts +0 -100
- package/src/discovery/reputation-verifier.ts +0 -54
- package/src/index.ts +0 -61
- package/src/interfaces/buyer-router.ts +0 -21
- package/src/interfaces/plugin.ts +0 -36
- package/src/interfaces/seller-provider.ts +0 -81
- package/src/metering/index.ts +0 -6
- package/src/metering/receipt-generator.ts +0 -105
- package/src/metering/receipt-verifier.ts +0 -102
- package/src/metering/session-tracker.ts +0 -145
- package/src/metering/storage.ts +0 -600
- package/src/metering/token-counter.ts +0 -127
- package/src/metering/usage-aggregator.ts +0 -236
- package/src/node.ts +0 -1698
- package/src/p2p/connection-auth.ts +0 -152
- package/src/p2p/connection-manager.ts +0 -916
- package/src/p2p/handshake.ts +0 -162
- package/src/p2p/ice-config.ts +0 -59
- package/src/p2p/identity.ts +0 -110
- package/src/p2p/index.ts +0 -11
- package/src/p2p/keepalive.ts +0 -118
- package/src/p2p/message-protocol.ts +0 -171
- package/src/p2p/nat-traversal.ts +0 -169
- package/src/p2p/payment-codec.ts +0 -165
- package/src/p2p/payment-mux.ts +0 -153
- package/src/p2p/reconnect.ts +0 -117
- package/src/payments/balance-manager.ts +0 -77
- package/src/payments/buyer-payment-manager.ts +0 -414
- package/src/payments/disputes.ts +0 -72
- package/src/payments/evm/escrow-client.ts +0 -263
- package/src/payments/evm/keypair.ts +0 -31
- package/src/payments/evm/signatures.ts +0 -103
- package/src/payments/evm/wallet.ts +0 -42
- package/src/payments/index.ts +0 -50
- package/src/payments/settlement.ts +0 -40
- package/src/payments/types.ts +0 -79
- package/src/proxy/index.ts +0 -3
- package/src/proxy/provider-detection.ts +0 -78
- package/src/proxy/proxy-mux.ts +0 -173
- package/src/proxy/request-codec.ts +0 -294
- package/src/reputation/index.ts +0 -6
- package/src/reputation/rating-manager.ts +0 -118
- package/src/reputation/report-manager.ts +0 -91
- package/src/reputation/trust-engine.ts +0 -120
- package/src/reputation/trust-score.ts +0 -74
- package/src/reputation/uptime-tracker.ts +0 -155
- package/src/routing/default-router.ts +0 -75
- package/src/types/bittorrent-dht.d.ts +0 -19
- package/src/types/buyer.ts +0 -37
- package/src/types/capability.ts +0 -34
- package/src/types/connection.ts +0 -29
- package/src/types/http.ts +0 -20
- package/src/types/index.ts +0 -14
- package/src/types/metering.ts +0 -175
- package/src/types/nat-api.d.ts +0 -29
- package/src/types/peer-profile.ts +0 -25
- package/src/types/peer.ts +0 -62
- package/src/types/plugin-config.ts +0 -31
- package/src/types/protocol.ts +0 -162
- package/src/types/provider.ts +0 -40
- package/src/types/rating.ts +0 -23
- package/src/types/report.ts +0 -30
- package/src/types/seller.ts +0 -38
- package/src/types/staking.ts +0 -23
- package/src/utils/debug.ts +0 -30
- package/src/utils/hex.ts +0 -14
- package/tests/balance-manager.test.ts +0 -156
- package/tests/bootstrap.test.ts +0 -108
- package/tests/buyer-payment-manager.test.ts +0 -358
- package/tests/connection-auth.test.ts +0 -87
- package/tests/default-router.test.ts +0 -148
- package/tests/evm-keypair.test.ts +0 -173
- package/tests/identity.test.ts +0 -133
- package/tests/message-protocol.test.ts +0 -212
- package/tests/metadata-codec.test.ts +0 -165
- package/tests/metadata-validator.test.ts +0 -261
- package/tests/metering-storage.test.ts +0 -244
- package/tests/payment-codec.test.ts +0 -95
- package/tests/payment-mux.test.ts +0 -191
- package/tests/peer-selector.test.ts +0 -184
- package/tests/provider-detection.test.ts +0 -107
- package/tests/proxy-mux-security.test.ts +0 -38
- package/tests/receipt.test.ts +0 -215
- package/tests/reputation-integration.test.ts +0 -195
- package/tests/request-codec.test.ts +0 -144
- package/tests/token-counter.test.ts +0 -122
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -7
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import { Contract, JsonRpcProvider, type AbstractSigner } from 'ethers';
|
|
2
|
-
|
|
3
|
-
export interface BaseEscrowConfig {
|
|
4
|
-
/** Base JSON-RPC endpoint (e.g. http://127.0.0.1:8545 for anvil) */
|
|
5
|
-
rpcUrl: string;
|
|
6
|
-
/** Deployed AntseedEscrow contract address */
|
|
7
|
-
contractAddress: string;
|
|
8
|
-
/** USDC token contract address */
|
|
9
|
-
usdcAddress: string;
|
|
10
|
-
/** Confirmation commitment level (not used on EVM, reserved for future) */
|
|
11
|
-
commitment?: 'latest' | 'finalized';
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface SessionInfo {
|
|
15
|
-
buyer: string;
|
|
16
|
-
seller: string;
|
|
17
|
-
lockedAmount: bigint;
|
|
18
|
-
status: number;
|
|
19
|
-
expiresAt: number;
|
|
20
|
-
settledAmount: bigint;
|
|
21
|
-
score: number;
|
|
22
|
-
disputeClaimedAmount: bigint;
|
|
23
|
-
disputeOpenedAt: number;
|
|
24
|
-
disputeBuyerResponded: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface ReputationInfo {
|
|
28
|
-
totalWeightedScore: bigint;
|
|
29
|
-
totalWeight: bigint;
|
|
30
|
-
sessionCount: number;
|
|
31
|
-
disputeCount: number;
|
|
32
|
-
weightedAverage: number;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const ESCROW_ABI = [
|
|
36
|
-
// Deposit & Withdraw
|
|
37
|
-
'function deposit(uint256 amount) external',
|
|
38
|
-
'function withdraw(uint256 amount) external',
|
|
39
|
-
|
|
40
|
-
// Session lifecycle
|
|
41
|
-
'function commitLock(bytes32 sessionId, address buyer, uint256 amount, bytes calldata buyerSig) external',
|
|
42
|
-
'function extendLock(bytes32 sessionId, uint256 additionalAmount, bytes calldata buyerSig) external',
|
|
43
|
-
'function settle(bytes32 sessionId, uint256 runningTotal, uint8 score, bytes calldata buyerSig) external',
|
|
44
|
-
|
|
45
|
-
// Disputes
|
|
46
|
-
'function openDispute(bytes32 sessionId, uint256 claimedAmount) external',
|
|
47
|
-
'function respondDispute(bytes32 sessionId) external',
|
|
48
|
-
'function resolveDispute(bytes32 sessionId) external',
|
|
49
|
-
|
|
50
|
-
// Expired lock
|
|
51
|
-
'function releaseExpiredLock(bytes32 sessionId) external',
|
|
52
|
-
|
|
53
|
-
// View functions
|
|
54
|
-
'function buyers(address) external view returns (uint256 deposited, uint256 committed)',
|
|
55
|
-
'function sessions(bytes32) external view returns (address buyer, address seller, uint256 lockedAmount, uint8 status, uint64 expiresAt, uint256 settledAmount, uint8 score, uint256 disputeClaimedAmount, uint64 disputeOpenedAt, bool disputeBuyerResponded, bool exists)',
|
|
56
|
-
'function reputations(address) external view returns (uint256 totalWeightedScore, uint256 totalWeight, uint256 sessionCount, uint256 disputeCount)',
|
|
57
|
-
] as const;
|
|
58
|
-
|
|
59
|
-
const ERC20_ABI = [
|
|
60
|
-
'function approve(address spender, uint256 amount) external returns (bool)',
|
|
61
|
-
'function balanceOf(address owner) external view returns (uint256)',
|
|
62
|
-
'function allowance(address owner, address spender) external view returns (uint256)',
|
|
63
|
-
] as const;
|
|
64
|
-
|
|
65
|
-
export class BaseEscrowClient {
|
|
66
|
-
private readonly _provider: JsonRpcProvider;
|
|
67
|
-
private readonly _contractAddress: string;
|
|
68
|
-
private readonly _usdcAddress: string;
|
|
69
|
-
private readonly _nonceCursor = new Map<string, number>();
|
|
70
|
-
|
|
71
|
-
constructor(config: BaseEscrowConfig) {
|
|
72
|
-
this._provider = new JsonRpcProvider(config.rpcUrl);
|
|
73
|
-
this._contractAddress = config.contractAddress;
|
|
74
|
-
this._usdcAddress = config.usdcAddress;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
get provider(): JsonRpcProvider { return this._provider; }
|
|
78
|
-
get contractAddress(): string { return this._contractAddress; }
|
|
79
|
-
get usdcAddress(): string { return this._usdcAddress; }
|
|
80
|
-
|
|
81
|
-
private _ensureConnected(signer: AbstractSigner): AbstractSigner {
|
|
82
|
-
if (signer.provider) {
|
|
83
|
-
return signer;
|
|
84
|
-
}
|
|
85
|
-
return signer.connect(this._provider);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private async reserveNonce(address: string): Promise<number> {
|
|
89
|
-
const networkNonce = await this._provider.getTransactionCount(address, 'pending');
|
|
90
|
-
const cachedNext = this._nonceCursor.get(address);
|
|
91
|
-
const nonce = cachedNext === undefined ? networkNonce : Math.max(networkNonce, cachedNext);
|
|
92
|
-
this._nonceCursor.set(address, nonce + 1);
|
|
93
|
-
return nonce;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
private async _prepareEscrowWrite(signer: AbstractSigner): Promise<{
|
|
97
|
-
contract: Contract;
|
|
98
|
-
nonce: number;
|
|
99
|
-
}> {
|
|
100
|
-
const connected = this._ensureConnected(signer);
|
|
101
|
-
const signerAddress = await connected.getAddress();
|
|
102
|
-
const nonce = await this.reserveNonce(signerAddress);
|
|
103
|
-
const contract = new Contract(this._contractAddress, ESCROW_ABI, connected);
|
|
104
|
-
return { contract, nonce };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async deposit(signer: AbstractSigner, amount: bigint): Promise<string> {
|
|
108
|
-
const connected = this._ensureConnected(signer);
|
|
109
|
-
const signerAddress = await connected.getAddress();
|
|
110
|
-
const usdc = new Contract(this._usdcAddress, ERC20_ABI, connected);
|
|
111
|
-
const approveNonce = await this.reserveNonce(signerAddress);
|
|
112
|
-
const approveTx = await usdc.getFunction('approve')(this._contractAddress, amount, { nonce: approveNonce });
|
|
113
|
-
await approveTx.wait();
|
|
114
|
-
const contract = new Contract(this._contractAddress, ESCROW_ABI, connected);
|
|
115
|
-
const depositNonce = await this.reserveNonce(signerAddress);
|
|
116
|
-
const tx = await contract.getFunction('deposit')(amount, { nonce: depositNonce });
|
|
117
|
-
const receipt = await tx.wait();
|
|
118
|
-
return receipt.hash;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async withdraw(signer: AbstractSigner, amount: bigint): Promise<string> {
|
|
122
|
-
const { contract, nonce } = await this._prepareEscrowWrite(signer);
|
|
123
|
-
const tx = await contract.getFunction('withdraw')(amount, { nonce });
|
|
124
|
-
const receipt = await tx.wait();
|
|
125
|
-
return receipt.hash;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async commitLock(
|
|
129
|
-
seller: AbstractSigner,
|
|
130
|
-
buyerAddr: string,
|
|
131
|
-
sessionId: string,
|
|
132
|
-
amount: bigint,
|
|
133
|
-
buyerSig: string,
|
|
134
|
-
): Promise<string> {
|
|
135
|
-
const { contract, nonce } = await this._prepareEscrowWrite(seller);
|
|
136
|
-
const tx = await contract.getFunction('commitLock')(sessionId, buyerAddr, amount, buyerSig, { nonce });
|
|
137
|
-
const receipt = await tx.wait();
|
|
138
|
-
return receipt.hash;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
async extendLock(
|
|
142
|
-
seller: AbstractSigner,
|
|
143
|
-
sessionId: string,
|
|
144
|
-
additionalAmount: bigint,
|
|
145
|
-
buyerSig: string,
|
|
146
|
-
): Promise<string> {
|
|
147
|
-
const { contract, nonce } = await this._prepareEscrowWrite(seller);
|
|
148
|
-
const tx = await contract.getFunction('extendLock')(sessionId, additionalAmount, buyerSig, { nonce });
|
|
149
|
-
const receipt = await tx.wait();
|
|
150
|
-
return receipt.hash;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async settle(
|
|
154
|
-
seller: AbstractSigner,
|
|
155
|
-
sessionId: string,
|
|
156
|
-
runningTotal: bigint,
|
|
157
|
-
score: number,
|
|
158
|
-
buyerSig: string,
|
|
159
|
-
): Promise<string> {
|
|
160
|
-
const { contract, nonce } = await this._prepareEscrowWrite(seller);
|
|
161
|
-
const tx = await contract.getFunction('settle')(sessionId, runningTotal, score, buyerSig, { nonce });
|
|
162
|
-
const receipt = await tx.wait();
|
|
163
|
-
return receipt.hash;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async openDispute(
|
|
167
|
-
caller: AbstractSigner,
|
|
168
|
-
sessionId: string,
|
|
169
|
-
claimedAmount: bigint,
|
|
170
|
-
): Promise<string> {
|
|
171
|
-
const { contract, nonce } = await this._prepareEscrowWrite(caller);
|
|
172
|
-
const tx = await contract.getFunction('openDispute')(sessionId, claimedAmount, { nonce });
|
|
173
|
-
const receipt = await tx.wait();
|
|
174
|
-
return receipt.hash;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
async respondDispute(
|
|
178
|
-
buyer: AbstractSigner,
|
|
179
|
-
sessionId: string,
|
|
180
|
-
): Promise<string> {
|
|
181
|
-
const { contract, nonce } = await this._prepareEscrowWrite(buyer);
|
|
182
|
-
const tx = await contract.getFunction('respondDispute')(sessionId, { nonce });
|
|
183
|
-
const receipt = await tx.wait();
|
|
184
|
-
return receipt.hash;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
async resolveDispute(
|
|
188
|
-
caller: AbstractSigner,
|
|
189
|
-
sessionId: string,
|
|
190
|
-
): Promise<string> {
|
|
191
|
-
const { contract, nonce } = await this._prepareEscrowWrite(caller);
|
|
192
|
-
const tx = await contract.getFunction('resolveDispute')(sessionId, { nonce });
|
|
193
|
-
const receipt = await tx.wait();
|
|
194
|
-
return receipt.hash;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
async releaseExpiredLock(
|
|
198
|
-
buyer: AbstractSigner,
|
|
199
|
-
sessionId: string,
|
|
200
|
-
): Promise<string> {
|
|
201
|
-
const { contract, nonce } = await this._prepareEscrowWrite(buyer);
|
|
202
|
-
const tx = await contract.getFunction('releaseExpiredLock')(sessionId, { nonce });
|
|
203
|
-
const receipt = await tx.wait();
|
|
204
|
-
return receipt.hash;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
async getBuyerAccount(buyerAddr: string): Promise<{
|
|
208
|
-
deposited: bigint;
|
|
209
|
-
committed: bigint;
|
|
210
|
-
available: bigint;
|
|
211
|
-
}> {
|
|
212
|
-
const contract = new Contract(this._contractAddress, ESCROW_ABI, this._provider);
|
|
213
|
-
const result = await contract.getFunction('buyers')(buyerAddr);
|
|
214
|
-
const deposited = result[0] as bigint;
|
|
215
|
-
const committed = result[1] as bigint;
|
|
216
|
-
return {
|
|
217
|
-
deposited,
|
|
218
|
-
committed,
|
|
219
|
-
available: deposited - committed,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
async getSession(sessionId: string): Promise<SessionInfo> {
|
|
224
|
-
const contract = new Contract(this._contractAddress, ESCROW_ABI, this._provider);
|
|
225
|
-
const result = await contract.getFunction('sessions')(sessionId);
|
|
226
|
-
return {
|
|
227
|
-
buyer: result[0],
|
|
228
|
-
seller: result[1],
|
|
229
|
-
lockedAmount: result[2],
|
|
230
|
-
status: Number(result[3]),
|
|
231
|
-
expiresAt: Number(result[4]),
|
|
232
|
-
settledAmount: result[5],
|
|
233
|
-
score: Number(result[6]),
|
|
234
|
-
disputeClaimedAmount: result[7],
|
|
235
|
-
disputeOpenedAt: Number(result[8]),
|
|
236
|
-
disputeBuyerResponded: result[9],
|
|
237
|
-
};
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
async getReputation(sellerAddr: string): Promise<ReputationInfo> {
|
|
241
|
-
const contract = new Contract(this._contractAddress, ESCROW_ABI, this._provider);
|
|
242
|
-
const result = await contract.getFunction('reputations')(sellerAddr);
|
|
243
|
-
const totalWeightedScore = result[0] as bigint;
|
|
244
|
-
const totalWeight = result[1] as bigint;
|
|
245
|
-
const sessionCount = Number(result[2]);
|
|
246
|
-
const disputeCount = Number(result[3]);
|
|
247
|
-
const weightedAverage = totalWeight > 0n
|
|
248
|
-
? Number(totalWeightedScore / totalWeight)
|
|
249
|
-
: 50;
|
|
250
|
-
return {
|
|
251
|
-
totalWeightedScore,
|
|
252
|
-
totalWeight,
|
|
253
|
-
sessionCount,
|
|
254
|
-
disputeCount,
|
|
255
|
-
weightedAverage,
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
async getUSDCBalance(ownerAddr: string): Promise<bigint> {
|
|
260
|
-
const usdc = new Contract(this._usdcAddress, ERC20_ABI, this._provider);
|
|
261
|
-
return usdc.getFunction('balanceOf')(ownerAddr) as Promise<bigint>;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Wallet, keccak256 } from 'ethers';
|
|
2
|
-
import type { Identity } from '../../p2p/identity.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Derive a secp256k1 private key from the Ed25519 identity seed.
|
|
6
|
-
* Domain-separated to ensure the derived key is independent from the Ed25519 key.
|
|
7
|
-
*
|
|
8
|
-
* Derivation: keccak256(ed25519_seed || "evm-payment-key") → secp256k1 private key
|
|
9
|
-
*
|
|
10
|
-
* The Ed25519 seed (identity.privateKey) is 32 bytes. We append a fixed
|
|
11
|
-
* domain separator string to prevent the derived key from colliding with
|
|
12
|
-
* any other use of the same seed. keccak256 produces a 32-byte output
|
|
13
|
-
* which is a valid secp256k1 private key (the probability of hitting an
|
|
14
|
-
* invalid key is astronomically low: ~1/2^128).
|
|
15
|
-
*/
|
|
16
|
-
export function identityToEvmWallet(identity: Identity): Wallet {
|
|
17
|
-
const domainSeparator = new TextEncoder().encode('evm-payment-key');
|
|
18
|
-
const combined = new Uint8Array(identity.privateKey.length + domainSeparator.length);
|
|
19
|
-
combined.set(identity.privateKey, 0);
|
|
20
|
-
combined.set(domainSeparator, identity.privateKey.length);
|
|
21
|
-
const privateKey = keccak256(combined);
|
|
22
|
-
return new Wallet(privateKey);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Get the EVM address (0x-prefixed hex) for a Antseed Identity.
|
|
27
|
-
* This is the address that appears on-chain as the buyer or seller.
|
|
28
|
-
*/
|
|
29
|
-
export function identityToEvmAddress(identity: Identity): string {
|
|
30
|
-
return identityToEvmWallet(identity).address;
|
|
31
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { type AbstractSigner, solidityPackedKeccak256, getBytes } from 'ethers';
|
|
2
|
-
import type { Identity } from '../../p2p/identity.js';
|
|
3
|
-
import { signData, verifySignature } from '../../p2p/identity.js';
|
|
4
|
-
|
|
5
|
-
// =========================================================================
|
|
6
|
-
// ECDSA signatures (on-chain) — verified by contract via ecrecover
|
|
7
|
-
// =========================================================================
|
|
8
|
-
|
|
9
|
-
export function buildLockMessageHash(
|
|
10
|
-
sessionId: string,
|
|
11
|
-
seller: string,
|
|
12
|
-
amount: bigint,
|
|
13
|
-
): string {
|
|
14
|
-
return solidityPackedKeccak256(
|
|
15
|
-
['bytes1', 'bytes32', 'address', 'uint256'],
|
|
16
|
-
['0x01', sessionId, seller, amount],
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function buildSettlementMessageHash(
|
|
21
|
-
sessionId: string,
|
|
22
|
-
runningTotal: bigint,
|
|
23
|
-
score: number,
|
|
24
|
-
): string {
|
|
25
|
-
return solidityPackedKeccak256(
|
|
26
|
-
['bytes32', 'uint256', 'uint8'],
|
|
27
|
-
[sessionId, runningTotal, score],
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function buildExtendLockMessageHash(
|
|
32
|
-
sessionId: string,
|
|
33
|
-
seller: string,
|
|
34
|
-
additionalAmount: bigint,
|
|
35
|
-
): string {
|
|
36
|
-
return solidityPackedKeccak256(
|
|
37
|
-
['bytes1', 'bytes32', 'address', 'uint256'],
|
|
38
|
-
['0x02', sessionId, seller, additionalAmount],
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function signMessageEcdsa(
|
|
43
|
-
signer: AbstractSigner,
|
|
44
|
-
messageHash: string,
|
|
45
|
-
): Promise<string> {
|
|
46
|
-
return signer.signMessage(getBytes(messageHash));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// =========================================================================
|
|
50
|
-
// Ed25519 signatures (off-chain P2P) — bilateral receipt proof
|
|
51
|
-
// =========================================================================
|
|
52
|
-
|
|
53
|
-
export function buildReceiptMessage(
|
|
54
|
-
sessionId: Uint8Array,
|
|
55
|
-
runningTotal: bigint,
|
|
56
|
-
requestCount: number,
|
|
57
|
-
responseHash: Uint8Array,
|
|
58
|
-
): Uint8Array {
|
|
59
|
-
if (sessionId.length !== 32) throw new Error(`sessionId must be 32 bytes, got ${sessionId.length}`);
|
|
60
|
-
if (responseHash.length !== 32) throw new Error(`responseHash must be 32 bytes, got ${responseHash.length}`);
|
|
61
|
-
const msg = new Uint8Array(76);
|
|
62
|
-
msg.set(sessionId, 0);
|
|
63
|
-
const totalBuf = new ArrayBuffer(8);
|
|
64
|
-
new DataView(totalBuf).setBigUint64(0, runningTotal, true);
|
|
65
|
-
msg.set(new Uint8Array(totalBuf), 32);
|
|
66
|
-
const countBuf = new ArrayBuffer(4);
|
|
67
|
-
new DataView(countBuf).setUint32(0, requestCount, true);
|
|
68
|
-
msg.set(new Uint8Array(countBuf), 40);
|
|
69
|
-
msg.set(responseHash, 44);
|
|
70
|
-
return msg;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function buildAckMessage(
|
|
74
|
-
sessionId: Uint8Array,
|
|
75
|
-
runningTotal: bigint,
|
|
76
|
-
requestCount: number,
|
|
77
|
-
): Uint8Array {
|
|
78
|
-
if (sessionId.length !== 32) throw new Error(`sessionId must be 32 bytes, got ${sessionId.length}`);
|
|
79
|
-
const msg = new Uint8Array(44);
|
|
80
|
-
msg.set(sessionId, 0);
|
|
81
|
-
const totalBuf = new ArrayBuffer(8);
|
|
82
|
-
new DataView(totalBuf).setBigUint64(0, runningTotal, true);
|
|
83
|
-
msg.set(new Uint8Array(totalBuf), 32);
|
|
84
|
-
const countBuf = new ArrayBuffer(4);
|
|
85
|
-
new DataView(countBuf).setUint32(0, requestCount, true);
|
|
86
|
-
msg.set(new Uint8Array(countBuf), 40);
|
|
87
|
-
return msg;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export async function signMessageEd25519(
|
|
91
|
-
identity: Identity,
|
|
92
|
-
message: Uint8Array,
|
|
93
|
-
): Promise<Uint8Array> {
|
|
94
|
-
return signData(identity.privateKey, message);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export async function verifyMessageEd25519(
|
|
98
|
-
publicKey: Uint8Array,
|
|
99
|
-
signature: Uint8Array,
|
|
100
|
-
message: Uint8Array,
|
|
101
|
-
): Promise<boolean> {
|
|
102
|
-
return verifySignature(publicKey, signature, message);
|
|
103
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { JsonRpcProvider, Contract, formatEther, formatUnits } from 'ethers';
|
|
2
|
-
import type { Identity } from '../../p2p/identity.js';
|
|
3
|
-
import type { WalletInfo, ChainId } from '../types.js';
|
|
4
|
-
import { identityToEvmWallet, identityToEvmAddress } from './keypair.js';
|
|
5
|
-
|
|
6
|
-
const ERC20_BALANCE_ABI = [
|
|
7
|
-
'function balanceOf(address owner) external view returns (uint256)',
|
|
8
|
-
] as const;
|
|
9
|
-
|
|
10
|
-
export async function getWalletInfo(
|
|
11
|
-
identity: Identity,
|
|
12
|
-
rpcUrl: string,
|
|
13
|
-
usdcAddress: string,
|
|
14
|
-
chainId: ChainId,
|
|
15
|
-
): Promise<WalletInfo> {
|
|
16
|
-
const wallet = identityToEvmWallet(identity);
|
|
17
|
-
const provider = new JsonRpcProvider(rpcUrl);
|
|
18
|
-
const address = wallet.address;
|
|
19
|
-
|
|
20
|
-
const ethBalance = await provider.getBalance(address);
|
|
21
|
-
const balanceETH = formatEther(ethBalance);
|
|
22
|
-
|
|
23
|
-
const usdc = new Contract(usdcAddress, ERC20_BALANCE_ABI, provider);
|
|
24
|
-
let balanceUSDC = '0';
|
|
25
|
-
try {
|
|
26
|
-
const usdcRaw: bigint = await usdc.getFunction('balanceOf')(address);
|
|
27
|
-
balanceUSDC = formatUnits(usdcRaw, 6);
|
|
28
|
-
} catch {
|
|
29
|
-
// Contract may not exist on local dev chain yet
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
address,
|
|
34
|
-
chainId,
|
|
35
|
-
balanceETH,
|
|
36
|
-
balanceUSDC,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function getAddress(identity: Identity): string {
|
|
41
|
-
return identityToEvmAddress(identity);
|
|
42
|
-
}
|
package/src/payments/index.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
// Payment types
|
|
2
|
-
export type {
|
|
3
|
-
PaymentMethod,
|
|
4
|
-
ChainId,
|
|
5
|
-
WalletInfo,
|
|
6
|
-
TransactionType,
|
|
7
|
-
Transaction,
|
|
8
|
-
PaymentConfig,
|
|
9
|
-
CryptoPaymentConfig,
|
|
10
|
-
SettlementResult,
|
|
11
|
-
DisputeStatus,
|
|
12
|
-
PaymentDispute,
|
|
13
|
-
} from './types.js';
|
|
14
|
-
|
|
15
|
-
// Balance tracking (local transaction history)
|
|
16
|
-
export { BalanceManager } from './balance-manager.js';
|
|
17
|
-
export type { UnifiedBalance } from './balance-manager.js';
|
|
18
|
-
|
|
19
|
-
// Off-chain settlement calculation
|
|
20
|
-
export { calculateSettlement, isSettlementWithinEscrow, calculateRefund } from './settlement.js';
|
|
21
|
-
|
|
22
|
-
// Off-chain dispute detection
|
|
23
|
-
export {
|
|
24
|
-
createDispute,
|
|
25
|
-
detectDiscrepancy,
|
|
26
|
-
resolveDispute,
|
|
27
|
-
isDisputeExpired,
|
|
28
|
-
calculateDisputedAmount,
|
|
29
|
-
DISPUTE_TIMEOUT_MS,
|
|
30
|
-
} from './disputes.js';
|
|
31
|
-
|
|
32
|
-
// Base/EVM integration
|
|
33
|
-
export { BaseEscrowClient } from './evm/escrow-client.js';
|
|
34
|
-
export type { BaseEscrowConfig, SessionInfo, ReputationInfo } from './evm/escrow-client.js';
|
|
35
|
-
export { identityToEvmWallet, identityToEvmAddress } from './evm/keypair.js';
|
|
36
|
-
export {
|
|
37
|
-
signMessageEcdsa,
|
|
38
|
-
signMessageEd25519,
|
|
39
|
-
buildLockMessageHash,
|
|
40
|
-
buildSettlementMessageHash,
|
|
41
|
-
buildExtendLockMessageHash,
|
|
42
|
-
buildReceiptMessage,
|
|
43
|
-
buildAckMessage,
|
|
44
|
-
verifyMessageEd25519,
|
|
45
|
-
} from './evm/signatures.js';
|
|
46
|
-
export { getWalletInfo, getAddress } from './evm/wallet.js';
|
|
47
|
-
|
|
48
|
-
// Buyer payment manager
|
|
49
|
-
export { BuyerPaymentManager } from './buyer-payment-manager.js';
|
|
50
|
-
export type { BuyerPaymentConfig, BuyerSessionState, BuyerSessionStatus } from './buyer-payment-manager.js';
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { UsageReceipt } from '../types/metering.js';
|
|
2
|
-
import type { SettlementResult } from './types.js';
|
|
3
|
-
|
|
4
|
-
export function calculateSettlement(
|
|
5
|
-
sessionId: string,
|
|
6
|
-
receipts: UsageReceipt[],
|
|
7
|
-
platformFeeRate: number,
|
|
8
|
-
): SettlementResult {
|
|
9
|
-
if (platformFeeRate < 0 || platformFeeRate > 1) {
|
|
10
|
-
throw new Error(`platformFeeRate must be between 0 and 1, got ${platformFeeRate}`);
|
|
11
|
-
}
|
|
12
|
-
const matching = receipts.filter((r) => r.sessionId === sessionId);
|
|
13
|
-
const totalTokens = matching.reduce((sum, r) => sum + r.tokens.totalTokens, 0);
|
|
14
|
-
const totalCostUSD = matching.reduce((sum, r) => sum + r.costCents, 0) / 100;
|
|
15
|
-
const platformFeeUSD = totalCostUSD * platformFeeRate;
|
|
16
|
-
const sellerPayoutUSD = totalCostUSD - platformFeeUSD;
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
sessionId,
|
|
20
|
-
receipts: matching,
|
|
21
|
-
totalTokens,
|
|
22
|
-
totalCostUSD,
|
|
23
|
-
platformFeeUSD,
|
|
24
|
-
sellerPayoutUSD,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function isSettlementWithinEscrow(
|
|
29
|
-
settlementCostUSD: number,
|
|
30
|
-
escrowAmountUSD: number,
|
|
31
|
-
): boolean {
|
|
32
|
-
return settlementCostUSD <= escrowAmountUSD;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function calculateRefund(
|
|
36
|
-
escrowAmountUSD: number,
|
|
37
|
-
settlementCostUSD: number,
|
|
38
|
-
): number {
|
|
39
|
-
return Math.max(0, escrowAmountUSD - settlementCostUSD);
|
|
40
|
-
}
|
package/src/payments/types.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { PeerId } from '../types/peer.js';
|
|
2
|
-
import type { UsageReceipt } from '../types/metering.js';
|
|
3
|
-
|
|
4
|
-
export type PaymentMethod = 'crypto';
|
|
5
|
-
|
|
6
|
-
export type ChainId = 'base-local' | 'base-sepolia' | 'base-mainnet';
|
|
7
|
-
|
|
8
|
-
export interface WalletInfo {
|
|
9
|
-
/** EVM address (0x-prefixed hex) */
|
|
10
|
-
address: string;
|
|
11
|
-
/** Base network */
|
|
12
|
-
chainId: ChainId;
|
|
13
|
-
/** ETH balance (formatted string, e.g. "0.05") — needed for gas on Base */
|
|
14
|
-
balanceETH: string;
|
|
15
|
-
/** USDC balance (formatted string, 6 decimals, e.g. "10.50") */
|
|
16
|
-
balanceUSDC: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type TransactionType =
|
|
20
|
-
| 'escrow_lock'
|
|
21
|
-
| 'escrow_release'
|
|
22
|
-
| 'escrow_refund'
|
|
23
|
-
| 'dispute_resolution';
|
|
24
|
-
|
|
25
|
-
export interface Transaction {
|
|
26
|
-
txId: string;
|
|
27
|
-
type: TransactionType;
|
|
28
|
-
amountUSD: number;
|
|
29
|
-
from: string;
|
|
30
|
-
to: string;
|
|
31
|
-
timestamp: number;
|
|
32
|
-
chainId?: ChainId;
|
|
33
|
-
txHash?: string;
|
|
34
|
-
status: 'pending' | 'confirmed' | 'failed';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface PaymentConfig {
|
|
38
|
-
crypto?: CryptoPaymentConfig;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface CryptoPaymentConfig {
|
|
42
|
-
/** Base network */
|
|
43
|
-
chainId: ChainId;
|
|
44
|
-
/** Base JSON-RPC URL (e.g. http://127.0.0.1:8545 for anvil) */
|
|
45
|
-
rpcUrl: string;
|
|
46
|
-
/** Deployed AntseedEscrow contract address */
|
|
47
|
-
contractAddress: string;
|
|
48
|
-
/** USDC token contract address */
|
|
49
|
-
usdcAddress: string;
|
|
50
|
-
/** Default lock amount for new sessions (USDC base units as string, e.g. "1000000" = 1 USDC) */
|
|
51
|
-
defaultLockAmountUSDC?: string;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface SettlementResult {
|
|
55
|
-
sessionId: string;
|
|
56
|
-
receipts: UsageReceipt[];
|
|
57
|
-
totalTokens: number;
|
|
58
|
-
totalCostUSD: number;
|
|
59
|
-
platformFeeUSD: number;
|
|
60
|
-
sellerPayoutUSD: number;
|
|
61
|
-
channelId?: string;
|
|
62
|
-
paymentTxHash?: string;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export type DisputeStatus = 'open' | 'resolved' | 'expired';
|
|
66
|
-
|
|
67
|
-
export interface PaymentDispute {
|
|
68
|
-
disputeId: string;
|
|
69
|
-
channelId: string;
|
|
70
|
-
sessionId: string;
|
|
71
|
-
initiatorPeerId: PeerId;
|
|
72
|
-
reason: string;
|
|
73
|
-
status: DisputeStatus;
|
|
74
|
-
buyerReceipts: UsageReceipt[];
|
|
75
|
-
sellerReceipts: UsageReceipt[];
|
|
76
|
-
createdAt: number;
|
|
77
|
-
resolvedAt: number | null;
|
|
78
|
-
resolution: string | null;
|
|
79
|
-
}
|
package/src/proxy/index.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export { ProxyMux } from './proxy-mux.js';
|
|
2
|
-
export { encodeHttpRequest, decodeHttpRequest, encodeHttpResponse, decodeHttpResponse, encodeHttpResponseChunk, decodeHttpResponseChunk } from './request-codec.js';
|
|
3
|
-
export { detectProviderFromHeaders, detectProviderFromPath, resolveProvider, IDLEAI_PROVIDER_HEADER } from './provider-detection.js';
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import type { ProviderType } from '../types/metering.js';
|
|
2
|
-
|
|
3
|
-
export const ANTSEED_PROVIDER_HEADER = 'x-antseed-provider';
|
|
4
|
-
/** @deprecated Use ANTSEED_PROVIDER_HEADER instead */
|
|
5
|
-
export const IDLEAI_PROVIDER_HEADER = ANTSEED_PROVIDER_HEADER;
|
|
6
|
-
|
|
7
|
-
const KNOWN_PROVIDERS = new Set<string>([
|
|
8
|
-
'anthropic',
|
|
9
|
-
'openai',
|
|
10
|
-
'google',
|
|
11
|
-
'moonshot',
|
|
12
|
-
]);
|
|
13
|
-
|
|
14
|
-
function getHeaderCaseInsensitive(
|
|
15
|
-
headers: Record<string, string>,
|
|
16
|
-
key: string
|
|
17
|
-
): string | undefined {
|
|
18
|
-
const target = key.toLowerCase();
|
|
19
|
-
for (const [headerName, value] of Object.entries(headers)) {
|
|
20
|
-
if (headerName.toLowerCase() === target) {
|
|
21
|
-
return value;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return undefined;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Return the provider encoded in an internal routing header, if valid.
|
|
29
|
-
*/
|
|
30
|
-
export function detectProviderFromHeaders(headers: Record<string, string>): ProviderType | null {
|
|
31
|
-
const raw = getHeaderCaseInsensitive(headers, ANTSEED_PROVIDER_HEADER);
|
|
32
|
-
if (!raw) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
const normalized = raw.trim().toLowerCase();
|
|
36
|
-
return KNOWN_PROVIDERS.has(normalized) ? normalized : null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Detect provider using request path heuristics.
|
|
41
|
-
*/
|
|
42
|
-
export function detectProviderFromPath(path: string): ProviderType | null {
|
|
43
|
-
const normalizedPath = path.toLowerCase();
|
|
44
|
-
|
|
45
|
-
// Must be evaluated before OpenAI checks since moonshot can share OpenAI-style paths.
|
|
46
|
-
if (normalizedPath.includes('moonshot')) {
|
|
47
|
-
return 'moonshot';
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (normalizedPath.startsWith('/v1/messages') || normalizedPath.startsWith('/v1/complete')) {
|
|
51
|
-
return 'anthropic';
|
|
52
|
-
}
|
|
53
|
-
if (
|
|
54
|
-
normalizedPath.startsWith('/v1/chat') ||
|
|
55
|
-
normalizedPath.startsWith('/v1/completions') ||
|
|
56
|
-
normalizedPath.startsWith('/v1/embeddings')
|
|
57
|
-
) {
|
|
58
|
-
return 'openai';
|
|
59
|
-
}
|
|
60
|
-
if (normalizedPath.startsWith('/v1beta/') || normalizedPath.startsWith('/v1/models/gemini')) {
|
|
61
|
-
return 'google';
|
|
62
|
-
}
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Resolve provider with priority:
|
|
68
|
-
* 1. explicit internal header
|
|
69
|
-
* 2. request path inference
|
|
70
|
-
* 3. fallback value
|
|
71
|
-
*/
|
|
72
|
-
export function resolveProvider(
|
|
73
|
-
path: string,
|
|
74
|
-
headers: Record<string, string>,
|
|
75
|
-
fallback: ProviderType
|
|
76
|
-
): ProviderType {
|
|
77
|
-
return detectProviderFromHeaders(headers) ?? detectProviderFromPath(path) ?? fallback;
|
|
78
|
-
}
|