Skip to content

Commit 35fcd32

Browse files
authored
Merge pull request #346 from csfloat/feature/notary-client
Implements Notary Proofs
2 parents 3685707 + 8771aff commit 35fcd32

23 files changed

+738
-2
lines changed

manifest.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848
"service_worker": "src/background.js",
4949
"type": "module"
5050
},
51-
"permissions": ["storage", "scripting", "alarms", "declarativeNetRequestWithHostAccess"],
51+
"minimum_chrome_version": "109",
52+
"permissions": ["storage", "scripting", "alarms", "declarativeNetRequestWithHostAccess", "offscreen"],
5253
"host_permissions": [
5354
"*://*.steamcommunity.com/market/listings/730/*",
5455
"*://*.steamcommunity.com/id/*/inventory*",
@@ -73,5 +74,8 @@
7374
"path": "src/steamcommunity_ruleset.json"
7475
}
7576
]
77+
},
78+
"content_security_policy": {
79+
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
7680
}
7781
}

package-lock.json

Lines changed: 130 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,10 @@
6666
"typescript": "^5.8.3",
6767
"webpack": "^5.98.0",
6868
"webpack-cli": "^6.0.1"
69+
},
70+
"dependencies": {
71+
"buffer": "^6.0.3",
72+
"comlink": "^4.4.2",
73+
"tlsn-js": "0.1.0-alpha.12.0"
6974
}
7075
}

src/environment.dev.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
export const environment = {
22
csfloat_base_api_url: 'http://localhost:8080/api',
3+
notary: {
4+
tlsn: 'https://notary.csfloat.com/tlsn/',
5+
ws: 'wss://notary.csfloat.com/ws/',
6+
loggingLevel: 'Error',
7+
},
38
};

src/environment.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
export const environment = {
22
csfloat_base_api_url: 'https://csfloat.com/api',
3+
notary: {
4+
tlsn: 'https://notary.csfloat.com/tlsn/',
5+
ws: 'wss://notary.csfloat.com/ws/',
6+
loggingLevel: 'Warn',
7+
},
38
};

src/lib/bridge/handlers/handlers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {FetchCSFloatMe} from './fetch_csfloat_me';
3333
import {PingRollbackTrade} from './ping_rollback_trade';
3434
import {FetchTradeHistory} from './fetch_trade_history';
3535
import {FetchSlimTrades} from './fetch_slim_trades';
36+
import {NotaryProve} from './notary_prove';
3637

3738
export const HANDLERS_MAP: {[key in RequestType]: RequestHandler<any, any>} = {
3839
[RequestType.EXECUTE_SCRIPT_ON_PAGE]: ExecuteScriptOnPage,
@@ -68,4 +69,5 @@ export const HANDLERS_MAP: {[key in RequestType]: RequestHandler<any, any>} = {
6869
[RequestType.PING_ROLLBACK_TRADE]: PingRollbackTrade,
6970
[RequestType.FETCH_TRADE_HISTORY]: FetchTradeHistory,
7071
[RequestType.FETCH_SLIM_TRADES]: FetchSlimTrades,
72+
[RequestType.NOTARY_PROVE]: NotaryProve,
7173
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {SimpleHandler} from './main';
2+
import {RequestType} from './types';
3+
import {SendToOffscreen} from '../../../offscreen/client';
4+
import {HasPermissions} from './has_permissions';
5+
import {NotaryProveRequest} from '../../notary/types';
6+
import {getAccessToken} from '../../alarms/access_token';
7+
import {PresentationJSON} from 'tlsn-js/build/types';
8+
import {
9+
OffscreenRequestType,
10+
TLSNProveOffscreenRequest,
11+
TLSNProveOffscreenResponse,
12+
} from '../../../offscreen/handlers/types';
13+
import {MaxConcurrency} from '../wrappers/cached';
14+
15+
export interface NotaryProveResponse {
16+
presentation: PresentationJSON;
17+
}
18+
19+
export const NotaryProve = MaxConcurrency(
20+
new SimpleHandler<NotaryProveRequest, NotaryProveResponse>(
21+
RequestType.NOTARY_PROVE,
22+
async (request: NotaryProveRequest): Promise<NotaryProveResponse> => {
23+
const steamPoweredPermissions = await HasPermissions.handleRequest(
24+
{
25+
permissions: [],
26+
origins: ['https://api.steampowered.com/*'],
27+
},
28+
{}
29+
);
30+
if (!steamPoweredPermissions.granted) {
31+
throw new Error('must have api.steampowered.com permissions in order to prove API requests');
32+
}
33+
34+
const access_token = await getAccessToken(request.expected_steam_id);
35+
36+
const response = await SendToOffscreen<TLSNProveOffscreenRequest, TLSNProveOffscreenResponse>(
37+
OffscreenRequestType.TLSN_PROVE,
38+
{
39+
notary_request: request,
40+
access_token,
41+
}
42+
);
43+
44+
return {
45+
presentation: response.presentation,
46+
};
47+
}
48+
),
49+
2
50+
);

src/lib/bridge/handlers/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ export enum RequestType {
3232
PING_ROLLBACK_TRADE = 30,
3333
FETCH_TRADE_HISTORY = 31,
3434
FETCH_SLIM_TRADES = 32,
35+
NOTARY_PROVE = 33,
3536
}

src/lib/bridge/wrappers/cached.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,14 @@ export class CachedHandler<Req, Resp> implements RequestHandler<Req, Resp> {
7575
return this.queue.fetch(request, sender);
7676
}
7777
}
78+
79+
/**
80+
* Sets max concurrency for the given handler. Requests in excess of this limit will block until the active
81+
* requests are finished. Uses a FIFO queue underneath.
82+
*
83+
* @param handler Handler to wrap with a max concurrency
84+
* @param maxConcurrency Max concurrency
85+
*/
86+
export function MaxConcurrency<Req, Resp>(handler: RequestHandler<Req, Resp>, maxConcurrency: number) {
87+
return new CachedHandler(handler, maxConcurrency, /* disable caching */ 0);
88+
}

src/lib/notary/types.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
export enum ProofType {
2+
TRADE_OFFERS = 'trade_offers',
3+
TRADE_OFFER = 'trade_offer',
4+
TRADE_HISTORY = 'trade_history',
5+
TRADE_STATUS = 'trade_status',
6+
}
7+
8+
interface ProveRequestPayloads {
9+
// IEconService/GetTradeOffers/v1/
10+
[ProofType.TRADE_OFFERS]: {
11+
get_sent_offers?: boolean;
12+
get_received_offers?: boolean;
13+
get_descriptions?: boolean;
14+
language?: string;
15+
active_only?: boolean;
16+
historical_only?: boolean;
17+
time_historical_cutoff?: number;
18+
cursor?: number;
19+
};
20+
// IEconService/GetTradeOffer/v1/
21+
[ProofType.TRADE_OFFER]: {
22+
tradeofferid: string;
23+
};
24+
// IEconService/GetTradeHistory/v1/
25+
[ProofType.TRADE_HISTORY]: {
26+
max_trades: number;
27+
start_after_time?: number;
28+
start_after_tradeid?: string;
29+
navigating_back?: boolean;
30+
get_descriptions?: boolean;
31+
language?: string;
32+
include_failed?: boolean;
33+
include_total?: boolean;
34+
};
35+
// IEconService/GetTradeStatus/v1/
36+
[ProofType.TRADE_STATUS]: {
37+
tradeid: string;
38+
get_descriptions?: boolean;
39+
language?: string;
40+
};
41+
}
42+
43+
export type NotaryProveRequest = {
44+
[T in ProofType]: {
45+
type: T;
46+
expected_steam_id?: string;
47+
} & ProveRequestPayloads[T];
48+
}[ProofType];

0 commit comments

Comments
 (0)