@antseed/node 0.2.96 → 0.2.98
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/discovery/announcer.d.ts +2 -0
- package/dist/discovery/announcer.d.ts.map +1 -1
- package/dist/discovery/announcer.js +6 -2
- package/dist/discovery/announcer.js.map +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +29 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +96 -0
- package/dist/node.js.map +1 -1
- package/dist/p2p/sweep-codec.d.ts +6 -0
- package/dist/p2p/sweep-codec.d.ts.map +1 -0
- package/dist/p2p/sweep-codec.js +73 -0
- package/dist/p2p/sweep-codec.js.map +1 -0
- package/dist/p2p/sweep-mux.d.ts +27 -0
- package/dist/p2p/sweep-mux.d.ts.map +1 -0
- package/dist/p2p/sweep-mux.js +70 -0
- package/dist/p2p/sweep-mux.js.map +1 -0
- package/dist/payments/buyer-free-usage-manager.d.ts +5 -0
- package/dist/payments/buyer-free-usage-manager.d.ts.map +1 -1
- package/dist/payments/buyer-free-usage-manager.js +22 -3
- package/dist/payments/buyer-free-usage-manager.js.map +1 -1
- package/dist/payments/buyer-payment-manager.d.ts +7 -0
- package/dist/payments/buyer-payment-manager.d.ts.map +1 -1
- package/dist/payments/buyer-payment-manager.js +45 -14
- package/dist/payments/buyer-payment-manager.js.map +1 -1
- package/dist/payments/chain-config.d.ts +3 -0
- package/dist/payments/chain-config.d.ts.map +1 -1
- package/dist/payments/chain-config.js +5 -1
- package/dist/payments/chain-config.js.map +1 -1
- package/dist/payments/deposit-relayer.d.ts +49 -0
- package/dist/payments/deposit-relayer.d.ts.map +1 -0
- package/dist/payments/deposit-relayer.js +184 -0
- package/dist/payments/deposit-relayer.js.map +1 -0
- package/dist/payments/evm/deposit-relay-client.d.ts +74 -0
- package/dist/payments/evm/deposit-relay-client.d.ts.map +1 -0
- package/dist/payments/evm/deposit-relay-client.js +114 -0
- package/dist/payments/evm/deposit-relay-client.js.map +1 -0
- package/dist/payments/evm/signatures.d.ts +48 -0
- package/dist/payments/evm/signatures.d.ts.map +1 -1
- package/dist/payments/evm/signatures.js +56 -1
- package/dist/payments/evm/signatures.js.map +1 -1
- package/dist/payments/seller-payment-manager.d.ts +2 -5
- package/dist/payments/seller-payment-manager.d.ts.map +1 -1
- package/dist/payments/seller-payment-manager.js +54 -88
- package/dist/payments/seller-payment-manager.js.map +1 -1
- package/dist/proxy/index.d.ts +1 -1
- package/dist/proxy/index.d.ts.map +1 -1
- package/dist/proxy/index.js +1 -1
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/service-api-adapter.d.ts +1 -1
- package/dist/proxy/service-api-adapter.d.ts.map +1 -1
- package/dist/proxy/service-api-adapter.js +1 -1
- package/dist/proxy/service-api-adapter.js.map +1 -1
- package/dist/types/protocol.d.ts +46 -0
- package/dist/types/protocol.d.ts.map +1 -1
- package/dist/types/protocol.js +9 -0
- package/dist/types/protocol.js.map +1 -1
- package/dist/utils/debug.d.ts +2 -0
- package/dist/utils/debug.d.ts.map +1 -1
- package/dist/utils/debug.js +30 -2
- package/dist/utils/debug.js.map +1 -1
- package/package.json +2 -2
- package/dist/payments/evm/subpool-client.d.ts +0 -32
- package/dist/payments/evm/subpool-client.d.ts.map +0 -1
- package/dist/payments/evm/subpool-client.js +0 -158
- package/dist/payments/evm/subpool-client.js.map +0 -1
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { verifyTypedData } from 'ethers';
|
|
2
|
+
import { DepositRelayClient } from './evm/deposit-relay-client.js';
|
|
3
|
+
import { RECEIVE_WITH_AUTHORIZATION_TYPES, makeUsdcDomain } from './evm/signatures.js';
|
|
4
|
+
import { debugLog, debugWarn } from '../utils/debug.js';
|
|
5
|
+
const DEFAULT_MIN_PROFIT = 0n;
|
|
6
|
+
const DEFAULT_MAX_IN_FLIGHT = 2;
|
|
7
|
+
const DEFAULT_MAX_PER_PEER_PER_MINUTE = 6;
|
|
8
|
+
const SEEN_NONCES_MAX = 1024;
|
|
9
|
+
const RATE_WINDOW_MS = 60_000;
|
|
10
|
+
/** Don't bother submitting when the authorization expires too soon to land. */
|
|
11
|
+
const MIN_REMAINING_VALIDITY_SECS = 30;
|
|
12
|
+
/**
|
|
13
|
+
* Seller-side permissionless relayer for buyer deposit sweeps.
|
|
14
|
+
*
|
|
15
|
+
* On SweepRequest: verify the buyer's EIP-3009 signature locally, simulate
|
|
16
|
+
* the call, check the fixed FEE clears gas cost by the configured minimum
|
|
17
|
+
* profit, then submit sweepDeposit with the seller's funded wallet and report
|
|
18
|
+
* progress via SweepReceipt. Losing a submission race to another relayer
|
|
19
|
+
* (EIP-3009 nonce already used) is normal — logged and dropped.
|
|
20
|
+
*/
|
|
21
|
+
export class DepositRelayer {
|
|
22
|
+
_identity;
|
|
23
|
+
_config;
|
|
24
|
+
_client;
|
|
25
|
+
_seenNonces = new Set();
|
|
26
|
+
_requestTimes = new Map();
|
|
27
|
+
_inFlight = 0;
|
|
28
|
+
constructor(identity, config) {
|
|
29
|
+
this._identity = identity;
|
|
30
|
+
this._config = config;
|
|
31
|
+
this._client = new DepositRelayClient({
|
|
32
|
+
rpcUrl: config.rpcUrl,
|
|
33
|
+
...(config.fallbackRpcUrls ? { fallbackRpcUrls: config.fallbackRpcUrls } : {}),
|
|
34
|
+
contractAddress: config.relayAddress,
|
|
35
|
+
evmChainId: config.evmChainId,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
get client() { return this._client; }
|
|
39
|
+
async handleSweepRequest(peerId, payload, mux) {
|
|
40
|
+
// Never submit to a contract a peer told us about — only our own config.
|
|
41
|
+
if (payload.evmChainId !== this._config.evmChainId ||
|
|
42
|
+
payload.relayAddress.toLowerCase() !== this._config.relayAddress.toLowerCase()) {
|
|
43
|
+
debugLog(`[Relayer] Dropping sweep from ${peerId.slice(0, 12)}...: chain/relay mismatch`);
|
|
44
|
+
return 'dropped';
|
|
45
|
+
}
|
|
46
|
+
const nonceKey = payload.nonce.toLowerCase();
|
|
47
|
+
if (this._seenNonces.has(nonceKey)) {
|
|
48
|
+
debugLog(`[Relayer] Dropping sweep from ${peerId.slice(0, 12)}...: nonce already seen`);
|
|
49
|
+
return 'dropped';
|
|
50
|
+
}
|
|
51
|
+
if (!this._admitPeerRequest(peerId)) {
|
|
52
|
+
debugWarn(`[Relayer] Rate limit exceeded for ${peerId.slice(0, 12)}...`);
|
|
53
|
+
return 'dropped';
|
|
54
|
+
}
|
|
55
|
+
const maxInFlight = this._config.maxInFlight ?? DEFAULT_MAX_IN_FLIGHT;
|
|
56
|
+
if (this._inFlight >= maxInFlight) {
|
|
57
|
+
debugLog(`[Relayer] Dropping sweep from ${peerId.slice(0, 12)}...: ${this._inFlight} sweeps already in flight`);
|
|
58
|
+
return 'dropped';
|
|
59
|
+
}
|
|
60
|
+
const nowSecs = Math.floor(Date.now() / 1000);
|
|
61
|
+
if (nowSecs <= payload.validAfter || nowSecs >= payload.validBefore - MIN_REMAINING_VALIDITY_SECS) {
|
|
62
|
+
this._sendReceipt(mux, payload, 'rejected', undefined, 'authorization window invalid or expiring');
|
|
63
|
+
return 'rejected';
|
|
64
|
+
}
|
|
65
|
+
let amount;
|
|
66
|
+
try {
|
|
67
|
+
amount = BigInt(payload.amount);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
this._sendReceipt(mux, payload, 'rejected', undefined, 'malformed amount');
|
|
71
|
+
return 'rejected';
|
|
72
|
+
}
|
|
73
|
+
if (!this._verifySignature(payload, amount)) {
|
|
74
|
+
this._sendReceipt(mux, payload, 'rejected', undefined, 'invalid signature');
|
|
75
|
+
return 'rejected';
|
|
76
|
+
}
|
|
77
|
+
this._rememberNonce(nonceKey);
|
|
78
|
+
const params = {
|
|
79
|
+
from: payload.from,
|
|
80
|
+
amount,
|
|
81
|
+
validAfter: BigInt(payload.validAfter),
|
|
82
|
+
validBefore: BigInt(payload.validBefore),
|
|
83
|
+
nonce: payload.nonce,
|
|
84
|
+
sig3009: payload.sig3009,
|
|
85
|
+
};
|
|
86
|
+
this._inFlight++;
|
|
87
|
+
try {
|
|
88
|
+
// Simulation failure (used nonce, bad sig, amount <= FEE, min-deposit,
|
|
89
|
+
// credit limit) → reject.
|
|
90
|
+
let estimate;
|
|
91
|
+
try {
|
|
92
|
+
estimate = await this._client.estimateSweepProfit(this._identity.wallet, params);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
96
|
+
debugLog(`[Relayer] Simulation failed for nonce ${payload.nonce.slice(0, 10)}...: ${message}`);
|
|
97
|
+
this._seenNonces.delete(nonceKey);
|
|
98
|
+
this._sendReceipt(mux, payload, 'rejected', undefined, 'simulation failed');
|
|
99
|
+
return 'rejected';
|
|
100
|
+
}
|
|
101
|
+
const minProfit = this._config.minProfitBaseUnits ?? DEFAULT_MIN_PROFIT;
|
|
102
|
+
if (estimate.profitUsdc < minProfit) {
|
|
103
|
+
debugLog(`[Relayer] Unprofitable sweep for nonce ${payload.nonce.slice(0, 10)}...: fee=${estimate.fee} gasEst=${estimate.estGasCostUsdc} profit=${estimate.profitUsdc} min=${minProfit}`);
|
|
104
|
+
this._seenNonces.delete(nonceKey);
|
|
105
|
+
this._sendReceipt(mux, payload, 'rejected', undefined, 'unprofitable for relayer');
|
|
106
|
+
return 'rejected';
|
|
107
|
+
}
|
|
108
|
+
this._sendReceipt(mux, payload, 'submitted');
|
|
109
|
+
const txHash = await this._client.sweep(this._identity.wallet, params);
|
|
110
|
+
debugLog(`[Relayer] Sweep confirmed for ${payload.from.slice(0, 10)}...: tx=${txHash} fee=${estimate.fee}`);
|
|
111
|
+
this._sendReceipt(mux, payload, 'confirmed', txHash);
|
|
112
|
+
return 'submitted';
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
// Losing the submission race (nonce consumed by another relayer) is normal.
|
|
116
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
117
|
+
debugLog(`[Relayer] Sweep submission failed for nonce ${payload.nonce.slice(0, 10)}...: ${message}`);
|
|
118
|
+
this._sendReceipt(mux, payload, 'rejected', undefined, 'submission failed');
|
|
119
|
+
return 'rejected';
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
this._inFlight--;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
_rememberNonce(nonceKey) {
|
|
126
|
+
this._seenNonces.add(nonceKey);
|
|
127
|
+
if (this._seenNonces.size > SEEN_NONCES_MAX) {
|
|
128
|
+
const oldest = this._seenNonces.values().next().value;
|
|
129
|
+
if (oldest !== undefined)
|
|
130
|
+
this._seenNonces.delete(oldest);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
_verifySignature(payload, amount) {
|
|
134
|
+
try {
|
|
135
|
+
const usdcDomain = makeUsdcDomain(this._config.evmChainId, this._config.usdcAddress);
|
|
136
|
+
const recovered = verifyTypedData(usdcDomain, RECEIVE_WITH_AUTHORIZATION_TYPES, {
|
|
137
|
+
from: payload.from,
|
|
138
|
+
to: this._config.relayAddress,
|
|
139
|
+
value: amount,
|
|
140
|
+
validAfter: BigInt(payload.validAfter),
|
|
141
|
+
validBefore: BigInt(payload.validBefore),
|
|
142
|
+
nonce: payload.nonce,
|
|
143
|
+
}, payload.sig3009);
|
|
144
|
+
return recovered.toLowerCase() === payload.from.toLowerCase();
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
_admitPeerRequest(peerId) {
|
|
151
|
+
const limit = this._config.maxPerPeerPerMinute ?? DEFAULT_MAX_PER_PEER_PER_MINUTE;
|
|
152
|
+
const now = Date.now();
|
|
153
|
+
const times = (this._requestTimes.get(peerId) ?? []).filter((t) => now - t < RATE_WINDOW_MS);
|
|
154
|
+
if (times.length >= limit) {
|
|
155
|
+
this._requestTimes.set(peerId, times);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
times.push(now);
|
|
159
|
+
this._requestTimes.set(peerId, times);
|
|
160
|
+
// Bound the map: drop stale peers opportunistically.
|
|
161
|
+
if (this._requestTimes.size > 512) {
|
|
162
|
+
for (const [key, value] of this._requestTimes) {
|
|
163
|
+
if (value.every((t) => now - t >= RATE_WINDOW_MS))
|
|
164
|
+
this._requestTimes.delete(key);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
_sendReceipt(mux, payload, status, txHash, reason) {
|
|
170
|
+
try {
|
|
171
|
+
mux.sendSweepReceipt({
|
|
172
|
+
version: 1,
|
|
173
|
+
authNonce: payload.nonce,
|
|
174
|
+
status,
|
|
175
|
+
...(txHash ? { txHash } : {}),
|
|
176
|
+
...(reason ? { reason } : {}),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
debugLog(`[Relayer] Failed to send receipt: ${err instanceof Error ? err.message : err}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=deposit-relayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deposit-relayer.js","sourceRoot":"","sources":["../../src/payments/deposit-relayer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { AbstractSigner, TypedDataDomain } from 'ethers';
|
|
2
|
+
import { BaseEvmClient } from './base-evm-client.js';
|
|
3
|
+
export interface DepositRelayClientConfig {
|
|
4
|
+
rpcUrl: string;
|
|
5
|
+
fallbackRpcUrls?: string[];
|
|
6
|
+
contractAddress: string;
|
|
7
|
+
evmChainId?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface SweepParams {
|
|
10
|
+
from: string;
|
|
11
|
+
amount: bigint;
|
|
12
|
+
validAfter: bigint;
|
|
13
|
+
validBefore: bigint;
|
|
14
|
+
nonce: string;
|
|
15
|
+
sig3009: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SweepProfitEstimate {
|
|
18
|
+
gasEstimate: bigint;
|
|
19
|
+
/** Estimated gas cost converted to USDC base units (6 decimals). */
|
|
20
|
+
estGasCostUsdc: bigint;
|
|
21
|
+
/** The contract's fixed FEE the relayer earns. */
|
|
22
|
+
fee: bigint;
|
|
23
|
+
/** fee - estGasCostUsdc; negative when relaying costs more than it pays. */
|
|
24
|
+
profitUsdc: bigint;
|
|
25
|
+
}
|
|
26
|
+
export interface SweepEventConfirmation {
|
|
27
|
+
txHash: string;
|
|
28
|
+
blockNumber: number;
|
|
29
|
+
buyer: string;
|
|
30
|
+
relayer: string;
|
|
31
|
+
deposited: bigint;
|
|
32
|
+
fee: bigint;
|
|
33
|
+
authNonce: string;
|
|
34
|
+
}
|
|
35
|
+
export declare class DepositRelayClient extends BaseEvmClient {
|
|
36
|
+
constructor(config: DepositRelayClientConfig);
|
|
37
|
+
sweep(signer: AbstractSigner, params: SweepParams): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Simulate the sweep and estimate the relayer's profit against the fixed
|
|
40
|
+
* FEE. Throws if the simulation reverts (bad signature, used nonce, expired
|
|
41
|
+
* window, min-deposit violation, ...) — callers should treat a throw as
|
|
42
|
+
* "do not relay".
|
|
43
|
+
*/
|
|
44
|
+
estimateSweepProfit(signer: AbstractSigner, params: SweepParams, opts?: {
|
|
45
|
+
ethPriceUsd?: bigint;
|
|
46
|
+
}): Promise<SweepProfitEstimate>;
|
|
47
|
+
/** The contract's fixed, immutable relayer fee in USDC base units. */
|
|
48
|
+
fee(): Promise<bigint>;
|
|
49
|
+
/**
|
|
50
|
+
* Confirm a relayer-reported transaction by reading its receipt and matching
|
|
51
|
+
* the relay's SweepExecuted event against the buyer authorization nonce.
|
|
52
|
+
*/
|
|
53
|
+
getSweepConfirmation(txHash: string, expected?: {
|
|
54
|
+
buyer?: string;
|
|
55
|
+
deposited?: bigint;
|
|
56
|
+
fee?: bigint;
|
|
57
|
+
authNonce?: string;
|
|
58
|
+
}): Promise<SweepEventConfirmation | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Check whether USDC has consumed the EIP-3009 authorization nonce. Because
|
|
61
|
+
* sweep authorizations are signed with `to = AntseedDepositRelay`, and the
|
|
62
|
+
* relay call is atomic, a consumed nonce is a strong fallback confirmation
|
|
63
|
+
* that the sweep transaction landed even when no relayer tx hash was reported.
|
|
64
|
+
*/
|
|
65
|
+
isAuthorizationUsed(usdcAddress: string, from: string, nonce: string): Promise<boolean>;
|
|
66
|
+
/**
|
|
67
|
+
* Compare a locally computed EIP-712 domain against the deployed USDC
|
|
68
|
+
* token's DOMAIN_SEPARATOR(). Circle's domain params (name/version) vary by
|
|
69
|
+
* deployment — call this before signing EIP-3009 authorizations so a
|
|
70
|
+
* mismatch fails loudly instead of producing signatures the token rejects.
|
|
71
|
+
*/
|
|
72
|
+
verifyUsdcDomain(usdcAddress: string, domain: TypedDataDomain): Promise<boolean>;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=deposit-relay-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deposit-relay-client.d.ts","sourceRoot":"","sources":["../../../src/payments/evm/deposit-relay-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAiBD,qBAAa,kBAAmB,SAAQ,aAAa;gBACvC,MAAM,EAAE,wBAAwB;IAMtC,KAAK,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAczE;;;;;OAKG;IACG,mBAAmB,CACvB,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,WAAW,EACnB,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9B,OAAO,CAAC,mBAAmB,CAAC;IA2B/B,sEAAsE;IAChE,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;IAK5B;;;OAGG;IACG,oBAAoB,CACxB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAuCzC;;;;;OAKG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7F;;;;;OAKG;IACG,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;CASvF"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Contract, Interface, TypedDataEncoder } from 'ethers';
|
|
2
|
+
import { BaseEvmClient } from './base-evm-client.js';
|
|
3
|
+
/** Conservative ETH/USD assumption for profitability checks when the caller
|
|
4
|
+
* provides no price. Overestimating ETH makes the check stricter, never
|
|
5
|
+
* unprofitable-but-accepted. */
|
|
6
|
+
const DEFAULT_ETH_PRICE_USD = 10000n;
|
|
7
|
+
const DEPOSIT_RELAY_ABI = [
|
|
8
|
+
'function sweepDeposit(address from, uint256 amount, uint256 validAfter, uint256 validBefore, bytes32 nonce, bytes sig3009) external',
|
|
9
|
+
'function FEE() external view returns (uint256)',
|
|
10
|
+
'function usdc() external view returns (address)',
|
|
11
|
+
'function deposits() external view returns (address)',
|
|
12
|
+
'event SweepExecuted(address indexed buyer, address indexed relayer, uint256 deposited, uint256 fee, bytes32 authNonce)',
|
|
13
|
+
];
|
|
14
|
+
const DEPOSIT_RELAY_INTERFACE = new Interface(DEPOSIT_RELAY_ABI);
|
|
15
|
+
export class DepositRelayClient extends BaseEvmClient {
|
|
16
|
+
constructor(config) {
|
|
17
|
+
super(config.rpcUrl, config.contractAddress, config.fallbackRpcUrls, config.evmChainId);
|
|
18
|
+
}
|
|
19
|
+
// ─── Relayer Operations ────────────────────────────────────────────
|
|
20
|
+
async sweep(signer, params) {
|
|
21
|
+
return this._execWrite(signer, DEPOSIT_RELAY_ABI, 'sweepDeposit', params.from, params.amount, params.validAfter, params.validBefore, params.nonce, params.sig3009);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Simulate the sweep and estimate the relayer's profit against the fixed
|
|
25
|
+
* FEE. Throws if the simulation reverts (bad signature, used nonce, expired
|
|
26
|
+
* window, min-deposit violation, ...) — callers should treat a throw as
|
|
27
|
+
* "do not relay".
|
|
28
|
+
*/
|
|
29
|
+
async estimateSweepProfit(signer, params, opts) {
|
|
30
|
+
const connected = this._ensureConnected(signer);
|
|
31
|
+
const contract = new Contract(this._contractAddress, DEPOSIT_RELAY_ABI, connected);
|
|
32
|
+
const populated = await contract.getFunction('sweepDeposit').populateTransaction(params.from, params.amount, params.validAfter, params.validBefore, params.nonce, params.sig3009);
|
|
33
|
+
const [gasEstimate, feeData, fee] = await Promise.all([
|
|
34
|
+
connected.estimateGas(populated),
|
|
35
|
+
this._provider.getFeeData(),
|
|
36
|
+
this.fee(),
|
|
37
|
+
]);
|
|
38
|
+
const gasPriceWei = feeData.maxFeePerGas ?? feeData.gasPrice ?? 0n;
|
|
39
|
+
const ethPriceUsd = opts?.ethPriceUsd ?? DEFAULT_ETH_PRICE_USD;
|
|
40
|
+
// wei * usd/eth → USDC base units (6 decimals): / 1e18 * 1e6 = / 1e12
|
|
41
|
+
const estGasCostUsdc = (gasEstimate * gasPriceWei * ethPriceUsd) / 10n ** 12n;
|
|
42
|
+
return { gasEstimate, estGasCostUsdc, fee, profitUsdc: fee - estGasCostUsdc };
|
|
43
|
+
}
|
|
44
|
+
// ─── View Functions ─────────────────────────────────────────────────
|
|
45
|
+
/** The contract's fixed, immutable relayer fee in USDC base units. */
|
|
46
|
+
async fee() {
|
|
47
|
+
const contract = new Contract(this._contractAddress, DEPOSIT_RELAY_ABI, this._provider);
|
|
48
|
+
return contract.getFunction('FEE')();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Confirm a relayer-reported transaction by reading its receipt and matching
|
|
52
|
+
* the relay's SweepExecuted event against the buyer authorization nonce.
|
|
53
|
+
*/
|
|
54
|
+
async getSweepConfirmation(txHash, expected) {
|
|
55
|
+
const receipt = await this._provider.getTransactionReceipt(txHash);
|
|
56
|
+
if (!receipt || receipt.status !== 1)
|
|
57
|
+
return null;
|
|
58
|
+
for (const log of receipt.logs) {
|
|
59
|
+
if (log.address.toLowerCase() !== this._contractAddress.toLowerCase())
|
|
60
|
+
continue;
|
|
61
|
+
const parsed = (() => {
|
|
62
|
+
try {
|
|
63
|
+
return DEPOSIT_RELAY_INTERFACE.parseLog(log);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
})();
|
|
69
|
+
if (!parsed || parsed.name !== 'SweepExecuted')
|
|
70
|
+
continue;
|
|
71
|
+
const args = parsed.args;
|
|
72
|
+
if (expected?.buyer && args.buyer.toLowerCase() !== expected.buyer.toLowerCase())
|
|
73
|
+
continue;
|
|
74
|
+
if (expected?.deposited !== undefined && args.deposited !== expected.deposited)
|
|
75
|
+
continue;
|
|
76
|
+
if (expected?.fee !== undefined && args.fee !== expected.fee)
|
|
77
|
+
continue;
|
|
78
|
+
if (expected?.authNonce && args.authNonce.toLowerCase() !== expected.authNonce.toLowerCase())
|
|
79
|
+
continue;
|
|
80
|
+
return {
|
|
81
|
+
txHash: receipt.hash,
|
|
82
|
+
blockNumber: receipt.blockNumber,
|
|
83
|
+
buyer: args.buyer,
|
|
84
|
+
relayer: args.relayer,
|
|
85
|
+
deposited: args.deposited,
|
|
86
|
+
fee: args.fee,
|
|
87
|
+
authNonce: args.authNonce,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check whether USDC has consumed the EIP-3009 authorization nonce. Because
|
|
94
|
+
* sweep authorizations are signed with `to = AntseedDepositRelay`, and the
|
|
95
|
+
* relay call is atomic, a consumed nonce is a strong fallback confirmation
|
|
96
|
+
* that the sweep transaction landed even when no relayer tx hash was reported.
|
|
97
|
+
*/
|
|
98
|
+
async isAuthorizationUsed(usdcAddress, from, nonce) {
|
|
99
|
+
const usdc = new Contract(usdcAddress, ['function authorizationState(address authorizer, bytes32 nonce) external view returns (bool)'], this._provider);
|
|
100
|
+
return usdc.getFunction('authorizationState')(from, nonce);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Compare a locally computed EIP-712 domain against the deployed USDC
|
|
104
|
+
* token's DOMAIN_SEPARATOR(). Circle's domain params (name/version) vary by
|
|
105
|
+
* deployment — call this before signing EIP-3009 authorizations so a
|
|
106
|
+
* mismatch fails loudly instead of producing signatures the token rejects.
|
|
107
|
+
*/
|
|
108
|
+
async verifyUsdcDomain(usdcAddress, domain) {
|
|
109
|
+
const usdc = new Contract(usdcAddress, ['function DOMAIN_SEPARATOR() external view returns (bytes32)'], this._provider);
|
|
110
|
+
const onChain = await usdc.getFunction('DOMAIN_SEPARATOR')();
|
|
111
|
+
return onChain.toLowerCase() === TypedDataEncoder.hashDomain(domain).toLowerCase();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=deposit-relay-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deposit-relay-client.js","sourceRoot":"","sources":["../../../src/payments/evm/deposit-relay-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,6 +29,22 @@ export declare const FREE_USAGE_AUTH_TYPES: {
|
|
|
29
29
|
type: string;
|
|
30
30
|
}[];
|
|
31
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* EIP-3009 receiveWithAuthorization typed data, as implemented by Circle's
|
|
34
|
+
* FiatToken (USDC). Must match the token's typehash exactly:
|
|
35
|
+
* ReceiveWithAuthorization(address from,address to,uint256 value,
|
|
36
|
+
* uint256 validAfter,uint256 validBefore,bytes32 nonce)
|
|
37
|
+
*
|
|
38
|
+
* For deposit sweeps this is the ONLY buyer signature: addressing the
|
|
39
|
+
* authorization to the AntseedDepositRelay contract is consent to its
|
|
40
|
+
* public, immutable fixed FEE.
|
|
41
|
+
*/
|
|
42
|
+
export declare const RECEIVE_WITH_AUTHORIZATION_TYPES: {
|
|
43
|
+
ReceiveWithAuthorization: {
|
|
44
|
+
name: string;
|
|
45
|
+
type: string;
|
|
46
|
+
}[];
|
|
47
|
+
};
|
|
32
48
|
export interface SpendingAuthMessage {
|
|
33
49
|
channelId: string;
|
|
34
50
|
cumulativeAmount: bigint;
|
|
@@ -53,6 +69,14 @@ export interface FreeUsageAuthMessage {
|
|
|
53
69
|
metadataHash: string;
|
|
54
70
|
deadline: bigint;
|
|
55
71
|
}
|
|
72
|
+
export interface ReceiveAuthorizationMessage {
|
|
73
|
+
from: string;
|
|
74
|
+
to: string;
|
|
75
|
+
value: bigint;
|
|
76
|
+
validAfter: bigint;
|
|
77
|
+
validBefore: bigint;
|
|
78
|
+
nonce: string;
|
|
79
|
+
}
|
|
56
80
|
/**
|
|
57
81
|
* SpendingAuth metadata v2.
|
|
58
82
|
*
|
|
@@ -148,9 +172,33 @@ export declare function computeFreeUsageChannelId(buyer: string, seller: string,
|
|
|
148
172
|
export declare function makeChannelsDomain(chainId: number, contractAddress: string): TypedDataDomain;
|
|
149
173
|
export declare function makeDepositsDomain(chainId: number, contractAddress: string): TypedDataDomain;
|
|
150
174
|
export declare function makeFreeUsageDomain(chainId: number, contractAddress: string): TypedDataDomain;
|
|
175
|
+
/**
|
|
176
|
+
* EIP-712 domain of Circle's USDC (FiatTokenV2). Verified against the deployed
|
|
177
|
+
* Base mainnet token (0x8335...2913): name "USD Coin", version "2". MockUSDC
|
|
178
|
+
* on base-local mirrors the same params. Callers with RPC access should verify
|
|
179
|
+
* via the token's DOMAIN_SEPARATOR() before first use (the params can differ
|
|
180
|
+
* on other deployments).
|
|
181
|
+
*/
|
|
182
|
+
export declare function makeUsdcDomain(chainId: number, usdcAddress: string): TypedDataDomain;
|
|
151
183
|
export declare function signSpendingAuth(signer: AbstractSigner, domain: TypedDataDomain, msg: SpendingAuthMessage): Promise<string>;
|
|
152
184
|
export declare function signReserveAuth(signer: AbstractSigner, domain: TypedDataDomain, msg: ReserveAuthMessage): Promise<string>;
|
|
153
185
|
export declare function signSetOperator(signer: AbstractSigner, domain: TypedDataDomain, msg: SetOperatorMessage): Promise<string>;
|
|
154
186
|
export declare function signFreeUsageOpen(signer: AbstractSigner, domain: TypedDataDomain, msg: FreeUsageOpenMessage): Promise<string>;
|
|
155
187
|
export declare function signFreeUsageAuth(signer: AbstractSigner, domain: TypedDataDomain, msg: FreeUsageAuthMessage): Promise<string>;
|
|
188
|
+
export interface SignedReceiveAuthorization {
|
|
189
|
+
message: ReceiveAuthorizationMessage;
|
|
190
|
+
signature: string;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Build and sign an EIP-3009 ReceiveWithAuthorization for USDC. Works with a
|
|
194
|
+
* provider-less signer — the hot wallet never needs RPC access to sign.
|
|
195
|
+
* A random 32-byte nonce is generated when none is supplied.
|
|
196
|
+
*/
|
|
197
|
+
export declare function buildReceiveAuthorization(signer: AbstractSigner, domain: TypedDataDomain, params: {
|
|
198
|
+
to: string;
|
|
199
|
+
value: bigint;
|
|
200
|
+
validAfter: bigint;
|
|
201
|
+
validBefore: bigint;
|
|
202
|
+
nonce?: string;
|
|
203
|
+
}): Promise<SignedReceiveAuthorization>;
|
|
156
204
|
//# sourceMappingURL=signatures.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signatures.d.ts","sourceRoot":"","sources":["../../../src/payments/evm/signatures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"signatures.d.ts","sourceRoot":"","sources":["../../../src/payments/evm/signatures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAiD,MAAM,QAAQ,CAAC;AAMlH,eAAO,MAAM,mBAAmB;;;;;CAM/B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;CAM9B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;CAK9B,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;CAKjC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;;;CAOjC,CAAC;AAMF;;;;;;;;;GASG;AACH,eAAO,MAAM,gCAAgC;;;;;CAS5C,CAAC;AAMF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAMD;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,oBAAoB;IACnC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,2BAA2B,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,2BAA2B,EAAE,MAAM,CAAC;IACpC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAKnC,wBAAgB,cAAc,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,CAerE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,EAAE,2BAA2B,EAAE,CAAA;CAAE,EACxF,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE,oBAAoB,GAC1B,CAAC,CAiCH;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,CAE1E;AAED,eAAO,MAAM,aAAa,EAAE,oBAK3B,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,MAA2C,CAAC;AAE7E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,2BAA2B,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,wBAAwB,GAAG,2BAA2B,CAAC;AAEnE,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAe3E;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAEhF;AAED,eAAO,MAAM,wBAAwB,EAAE,iBAKtC,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,MAA+D,CAAC;AAM5G;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,MAAM,CAMR;AAED,eAAO,MAAM,yBAAyB,QAAmC,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,MAAM,CAMR;AAMD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,eAAe,CAO5F;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,eAAe,CAO5F;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,eAAe,CAO7F;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe,CAOpF;AAMD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,kBAAkB,GACtB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,2BAA2B,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE;IACN,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACA,OAAO,CAAC,0BAA0B,CAAC,CAWrC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbiCoder, id, keccak256 } from 'ethers';
|
|
1
|
+
import { AbiCoder, hexlify, id, keccak256, randomBytes } from 'ethers';
|
|
2
2
|
// =========================================================================
|
|
3
3
|
// EIP-712 Types — AntSeed SpendingAuth (cumulative payment authorization)
|
|
4
4
|
// =========================================================================
|
|
@@ -36,6 +36,29 @@ export const FREE_USAGE_AUTH_TYPES = {
|
|
|
36
36
|
{ name: 'deadline', type: 'uint256' },
|
|
37
37
|
],
|
|
38
38
|
};
|
|
39
|
+
// =========================================================================
|
|
40
|
+
// EIP-712 Types — EIP-3009 (USDC)
|
|
41
|
+
// =========================================================================
|
|
42
|
+
/**
|
|
43
|
+
* EIP-3009 receiveWithAuthorization typed data, as implemented by Circle's
|
|
44
|
+
* FiatToken (USDC). Must match the token's typehash exactly:
|
|
45
|
+
* ReceiveWithAuthorization(address from,address to,uint256 value,
|
|
46
|
+
* uint256 validAfter,uint256 validBefore,bytes32 nonce)
|
|
47
|
+
*
|
|
48
|
+
* For deposit sweeps this is the ONLY buyer signature: addressing the
|
|
49
|
+
* authorization to the AntseedDepositRelay contract is consent to its
|
|
50
|
+
* public, immutable fixed FEE.
|
|
51
|
+
*/
|
|
52
|
+
export const RECEIVE_WITH_AUTHORIZATION_TYPES = {
|
|
53
|
+
ReceiveWithAuthorization: [
|
|
54
|
+
{ name: 'from', type: 'address' },
|
|
55
|
+
{ name: 'to', type: 'address' },
|
|
56
|
+
{ name: 'value', type: 'uint256' },
|
|
57
|
+
{ name: 'validAfter', type: 'uint256' },
|
|
58
|
+
{ name: 'validBefore', type: 'uint256' },
|
|
59
|
+
{ name: 'nonce', type: 'bytes32' },
|
|
60
|
+
],
|
|
61
|
+
};
|
|
39
62
|
export const METADATA_VERSION = 2n;
|
|
40
63
|
const SERVICE_METADATA_ABI_TYPE = 'tuple(bytes32 serviceId,uint256 cumulativeAmount,uint256 cumulativeInputTokens,uint256 cumulativeCachedInputTokens,uint256 cumulativeOutputTokens,uint256 cumulativeRequestCount)[]';
|
|
41
64
|
export function encodeMetadata(metadata) {
|
|
@@ -161,6 +184,21 @@ export function makeFreeUsageDomain(chainId, contractAddress) {
|
|
|
161
184
|
verifyingContract: contractAddress,
|
|
162
185
|
};
|
|
163
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* EIP-712 domain of Circle's USDC (FiatTokenV2). Verified against the deployed
|
|
189
|
+
* Base mainnet token (0x8335...2913): name "USD Coin", version "2". MockUSDC
|
|
190
|
+
* on base-local mirrors the same params. Callers with RPC access should verify
|
|
191
|
+
* via the token's DOMAIN_SEPARATOR() before first use (the params can differ
|
|
192
|
+
* on other deployments).
|
|
193
|
+
*/
|
|
194
|
+
export function makeUsdcDomain(chainId, usdcAddress) {
|
|
195
|
+
return {
|
|
196
|
+
name: 'USD Coin',
|
|
197
|
+
version: '2',
|
|
198
|
+
chainId,
|
|
199
|
+
verifyingContract: usdcAddress,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
164
202
|
// =========================================================================
|
|
165
203
|
// Signing functions — EIP-712 (on-chain)
|
|
166
204
|
// =========================================================================
|
|
@@ -179,4 +217,21 @@ export async function signFreeUsageOpen(signer, domain, msg) {
|
|
|
179
217
|
export async function signFreeUsageAuth(signer, domain, msg) {
|
|
180
218
|
return signer.signTypedData(domain, FREE_USAGE_AUTH_TYPES, msg);
|
|
181
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Build and sign an EIP-3009 ReceiveWithAuthorization for USDC. Works with a
|
|
222
|
+
* provider-less signer — the hot wallet never needs RPC access to sign.
|
|
223
|
+
* A random 32-byte nonce is generated when none is supplied.
|
|
224
|
+
*/
|
|
225
|
+
export async function buildReceiveAuthorization(signer, domain, params) {
|
|
226
|
+
const message = {
|
|
227
|
+
from: await signer.getAddress(),
|
|
228
|
+
to: params.to,
|
|
229
|
+
value: params.value,
|
|
230
|
+
validAfter: params.validAfter,
|
|
231
|
+
validBefore: params.validBefore,
|
|
232
|
+
nonce: params.nonce ?? hexlify(randomBytes(32)),
|
|
233
|
+
};
|
|
234
|
+
const signature = await signer.signTypedData(domain, RECEIVE_WITH_AUTHORIZATION_TYPES, message);
|
|
235
|
+
return { message, signature };
|
|
236
|
+
}
|
|
182
237
|
//# sourceMappingURL=signatures.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signatures.js","sourceRoot":"","sources":["../../../src/payments/evm/signatures.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6C,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"signatures.js","sourceRoot":"","sources":["../../../src/payments/evm/signatures.ts"],"names":[],"mappings":"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"}
|
|
@@ -129,19 +129,16 @@ export declare class SellerPaymentManager {
|
|
|
129
129
|
*/
|
|
130
130
|
waitForPendingAuths(buyerPeerId: string): Promise<void>;
|
|
131
131
|
private _handleSpendingAuthInner;
|
|
132
|
+
private _metadataMatchesHash;
|
|
132
133
|
private _storePendingTopUp;
|
|
133
134
|
private _formatError;
|
|
134
135
|
private _classifyTopUpFailure;
|
|
136
|
+
private _isRetryableTxSubmissionFailure;
|
|
135
137
|
private _flattenErrorText;
|
|
136
138
|
private _settleLatestAuth;
|
|
137
139
|
private _retryPendingTopUp;
|
|
138
140
|
private _recoverOnChainSession;
|
|
139
141
|
private _activateSession;
|
|
140
|
-
/**
|
|
141
|
-
* Validate and accept a SpendingAuth attached to an incoming request.
|
|
142
|
-
* Returns true if the buyer has sufficient budget to serve this request.
|
|
143
|
-
*/
|
|
144
|
-
validateAndAcceptAuth(buyerPeerId: string, auth: SpendingAuthPayload): Promise<boolean>;
|
|
145
142
|
/**
|
|
146
143
|
* Record USDC consumption after serving a request.
|
|
147
144
|
*/
|