@satelink/sdk 0.2.0
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/README.md +240 -0
- package/dist/adapters.d.ts +113 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +178 -0
- package/dist/adapters.js.map +1 -0
- package/dist/ai.d.ts +12 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +71 -0
- package/dist/ai.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/mev.d.ts +101 -0
- package/dist/mev.d.ts.map +1 -0
- package/dist/mev.js +133 -0
- package/dist/mev.js.map +1 -0
- package/dist/provider.d.ts +36 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +97 -0
- package/dist/provider.js.map +1 -0
- package/dist/rpc.d.ts +32 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +101 -0
- package/dist/rpc.js.map +1 -0
- package/dist/types.d.ts +66 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/eslint.config.js +1 -0
- package/package.json +71 -0
- package/src/adapters.ts +207 -0
- package/src/ai.ts +100 -0
- package/src/index.ts +43 -0
- package/src/mev.ts +213 -0
- package/src/provider.ts +134 -0
- package/src/rpc.ts +132 -0
- package/src/types.ts +73 -0
- package/tsconfig.json +19 -0
package/src/provider.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EIP-1193 Compatible Provider
|
|
3
|
+
* S4-003: Standard Ethereum provider interface for Satelink RPC
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
type RequestArguments = {
|
|
7
|
+
method: string;
|
|
8
|
+
params?: unknown[] | object;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type EventHandler = (...args: unknown[]) => void;
|
|
12
|
+
|
|
13
|
+
export interface EIP1193Provider {
|
|
14
|
+
request(args: RequestArguments): Promise<unknown>;
|
|
15
|
+
on(event: string, handler: EventHandler): void;
|
|
16
|
+
removeListener(event: string, handler: EventHandler): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface SatelinkProviderOptions {
|
|
20
|
+
chainId?: number;
|
|
21
|
+
apiKey?: string;
|
|
22
|
+
baseUrl?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const CHAIN_MAP: Record<number, string> = {
|
|
26
|
+
1: 'ethereum',
|
|
27
|
+
137: 'polygon',
|
|
28
|
+
80002: 'polygon-amoy',
|
|
29
|
+
42161: 'arbitrum',
|
|
30
|
+
8453: 'base'
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export class SatelinkProvider implements EIP1193Provider {
|
|
34
|
+
private _chainId: number;
|
|
35
|
+
private _apiKey: string;
|
|
36
|
+
private _baseUrl: string;
|
|
37
|
+
private _listeners: Map<string, Set<EventHandler>> = new Map();
|
|
38
|
+
|
|
39
|
+
constructor(options: SatelinkProviderOptions = {}) {
|
|
40
|
+
this._chainId = options.chainId || 137;
|
|
41
|
+
this._apiKey = options.apiKey || '';
|
|
42
|
+
this._baseUrl = options.baseUrl || 'https://rpc.satelink.network';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get chainId(): string {
|
|
46
|
+
return `0x${this._chainId.toString(16)}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get connected(): boolean {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async request({ method, params }: RequestArguments): Promise<unknown> {
|
|
54
|
+
if (method === 'eth_chainId') {
|
|
55
|
+
return this.chainId;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (method === 'eth_accounts' || method === 'eth_requestAccounts') {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (method === 'wallet_switchEthereumChain') {
|
|
63
|
+
const chainIdHex = (params as { chainId: string }[])?.[0]?.chainId;
|
|
64
|
+
if (chainIdHex) {
|
|
65
|
+
const newChainId = parseInt(chainIdHex, 16);
|
|
66
|
+
if (CHAIN_MAP[newChainId]) {
|
|
67
|
+
const oldChainId = this._chainId;
|
|
68
|
+
this._chainId = newChainId;
|
|
69
|
+
if (oldChainId !== newChainId) {
|
|
70
|
+
this._emit('chainChanged', this.chainId);
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
throw { code: 4902, message: 'Chain not supported' };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const chain = CHAIN_MAP[this._chainId] || 'polygon';
|
|
79
|
+
const url = `${this._baseUrl}/rpc/${chain}`;
|
|
80
|
+
|
|
81
|
+
const headers: Record<string, string> = {
|
|
82
|
+
'Content-Type': 'application/json'
|
|
83
|
+
};
|
|
84
|
+
if (this._apiKey) {
|
|
85
|
+
headers['X-API-Key'] = this._apiKey;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const response = await fetch(url, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers,
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
jsonrpc: '2.0',
|
|
93
|
+
id: Date.now(),
|
|
94
|
+
method,
|
|
95
|
+
params: params || []
|
|
96
|
+
})
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const data = await response.json();
|
|
100
|
+
|
|
101
|
+
if (data.error) {
|
|
102
|
+
throw {
|
|
103
|
+
code: data.error.code || -32000,
|
|
104
|
+
message: data.error.message || 'RPC error'
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return data.result;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
on(event: string, handler: EventHandler): void {
|
|
112
|
+
if (!this._listeners.has(event)) {
|
|
113
|
+
this._listeners.set(event, new Set());
|
|
114
|
+
}
|
|
115
|
+
this._listeners.get(event)!.add(handler);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
removeListener(event: string, handler: EventHandler): void {
|
|
119
|
+
this._listeners.get(event)?.delete(handler);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private _emit(event: string, ...args: unknown[]): void {
|
|
123
|
+
this._listeners.get(event)?.forEach(handler => handler(...args));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
disconnect(): void {
|
|
127
|
+
this._emit('disconnect', { code: 1000, message: 'User disconnected' });
|
|
128
|
+
this._listeners.clear();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function createSatelinkProvider(options?: SatelinkProviderOptions): SatelinkProvider {
|
|
133
|
+
return new SatelinkProvider(options);
|
|
134
|
+
}
|
package/src/rpc.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { SatelinkRPCOptions, JsonRpcRequest, JsonRpcResponse, TransactionRequest } from './types.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_BASE_URL = 'https://rpc.satelink.network';
|
|
4
|
+
const DEFAULT_CHAIN = 'polygon';
|
|
5
|
+
|
|
6
|
+
export class SatelinkRPC {
|
|
7
|
+
private apiKey?: string;
|
|
8
|
+
private chain: string;
|
|
9
|
+
private baseUrl: string;
|
|
10
|
+
private requestId = 0;
|
|
11
|
+
|
|
12
|
+
constructor(options: SatelinkRPCOptions = {}) {
|
|
13
|
+
this.apiKey = options.apiKey;
|
|
14
|
+
this.chain = options.chain || DEFAULT_CHAIN;
|
|
15
|
+
this.baseUrl = options.baseUrl || DEFAULT_BASE_URL;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private getNextId(): number {
|
|
19
|
+
return ++this.requestId;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private getRpcUrl(): string {
|
|
23
|
+
return `${this.baseUrl}/rpc/${this.chain}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async request<T = unknown>(method: string, params: unknown[] = []): Promise<T> {
|
|
27
|
+
const body: JsonRpcRequest = {
|
|
28
|
+
jsonrpc: '2.0',
|
|
29
|
+
method,
|
|
30
|
+
params,
|
|
31
|
+
id: this.getNextId()
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const headers: Record<string, string> = {
|
|
35
|
+
'Content-Type': 'application/json'
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
if (this.apiKey) {
|
|
39
|
+
headers['x-api-key'] = this.apiKey;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const response = await fetch(this.getRpcUrl(), {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
headers,
|
|
45
|
+
body: JSON.stringify(body)
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`RPC request failed: ${response.status} ${response.statusText}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const data: JsonRpcResponse<T> = await response.json();
|
|
53
|
+
|
|
54
|
+
if (data.error) {
|
|
55
|
+
throw new Error(`RPC error: ${data.error.message} (code: ${data.error.code})`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return data.result as T;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async getBlockNumber(): Promise<bigint> {
|
|
62
|
+
const result = await this.request<string>('eth_blockNumber');
|
|
63
|
+
return BigInt(result);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async getBalance(address: string, block: string = 'latest'): Promise<bigint> {
|
|
67
|
+
const result = await this.request<string>('eth_getBalance', [address, block]);
|
|
68
|
+
return BigInt(result);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async getTransactionCount(address: string, block: string = 'latest'): Promise<bigint> {
|
|
72
|
+
const result = await this.request<string>('eth_getTransactionCount', [address, block]);
|
|
73
|
+
return BigInt(result);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async call(tx: TransactionRequest, block: string = 'latest'): Promise<string> {
|
|
77
|
+
return this.request<string>('eth_call', [tx, block]);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async estimateGas(tx: TransactionRequest): Promise<bigint> {
|
|
81
|
+
const result = await this.request<string>('eth_estimateGas', [tx]);
|
|
82
|
+
return BigInt(result);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async getGasPrice(): Promise<bigint> {
|
|
86
|
+
const result = await this.request<string>('eth_gasPrice');
|
|
87
|
+
return BigInt(result);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async sendRawTransaction(signedTx: string): Promise<string> {
|
|
91
|
+
return this.request<string>('eth_sendRawTransaction', [signedTx]);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async getTransactionByHash(hash: string): Promise<unknown> {
|
|
95
|
+
return this.request('eth_getTransactionByHash', [hash]);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async getTransactionReceipt(hash: string): Promise<unknown> {
|
|
99
|
+
return this.request('eth_getTransactionReceipt', [hash]);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async getBlockByNumber(block: string | number, fullTx: boolean = false): Promise<unknown> {
|
|
103
|
+
const blockParam = typeof block === 'number' ? `0x${block.toString(16)}` : block;
|
|
104
|
+
return this.request('eth_getBlockByNumber', [blockParam, fullTx]);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async getChainId(): Promise<bigint> {
|
|
108
|
+
const result = await this.request<string>('eth_chainId');
|
|
109
|
+
return BigInt(result);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
setChain(chain: string): void {
|
|
113
|
+
this.chain = chain;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
toProvider(): EIP1193Provider {
|
|
117
|
+
return {
|
|
118
|
+
request: async ({ method, params }: { method: string; params?: unknown[] }) => {
|
|
119
|
+
return this.request(method, params || []);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface EIP1193Provider {
|
|
126
|
+
request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function createProvider(options: SatelinkRPCOptions = {}): EIP1193Provider {
|
|
130
|
+
const rpc = new SatelinkRPC(options);
|
|
131
|
+
return rpc.toProvider();
|
|
132
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export interface SatelinkRPCOptions {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
chain?: string;
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface SatelinkAIOptions {
|
|
8
|
+
apiKey: string;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface JsonRpcRequest {
|
|
13
|
+
jsonrpc: '2.0';
|
|
14
|
+
method: string;
|
|
15
|
+
params?: unknown[];
|
|
16
|
+
id: number | string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface JsonRpcResponse<T = unknown> {
|
|
20
|
+
jsonrpc: '2.0';
|
|
21
|
+
id: number | string;
|
|
22
|
+
result?: T;
|
|
23
|
+
error?: {
|
|
24
|
+
code: number;
|
|
25
|
+
message: string;
|
|
26
|
+
data?: unknown;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ChatMessage {
|
|
31
|
+
role: 'system' | 'user' | 'assistant';
|
|
32
|
+
content: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ChatCompletionOptions {
|
|
36
|
+
model?: string;
|
|
37
|
+
max_tokens?: number;
|
|
38
|
+
temperature?: number;
|
|
39
|
+
stream?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ChatCompletionResponse {
|
|
43
|
+
id: string;
|
|
44
|
+
object: 'chat.completion';
|
|
45
|
+
created: number;
|
|
46
|
+
model: string;
|
|
47
|
+
choices: Array<{
|
|
48
|
+
index: number;
|
|
49
|
+
message: ChatMessage;
|
|
50
|
+
finish_reason: string;
|
|
51
|
+
}>;
|
|
52
|
+
usage: {
|
|
53
|
+
prompt_tokens: number;
|
|
54
|
+
completion_tokens: number;
|
|
55
|
+
total_tokens: number;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface Model {
|
|
60
|
+
id: string;
|
|
61
|
+
object: 'model';
|
|
62
|
+
owned_by: string;
|
|
63
|
+
created: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface TransactionRequest {
|
|
67
|
+
to?: string;
|
|
68
|
+
from?: string;
|
|
69
|
+
data?: string;
|
|
70
|
+
value?: string;
|
|
71
|
+
gas?: string;
|
|
72
|
+
gasPrice?: string;
|
|
73
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022", "DOM"],
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"declaration": true,
|
|
14
|
+
"declarationMap": true,
|
|
15
|
+
"sourceMap": true
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*"],
|
|
18
|
+
"exclude": ["node_modules", "dist"]
|
|
19
|
+
}
|