@thryx/sdk 1.0.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/dist/index.d.mts +581 -0
- package/dist/index.d.ts +581 -0
- package/dist/index.js +345 -0
- package/dist/index.mjs +316 -0
- package/package.json +61 -0
- package/src/abis.ts +69 -0
- package/src/index.ts +440 -0
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thryx/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "TypeScript SDK for THRYX - AI-Native Blockchain (Chain ID: 77777)",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
17
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
18
|
+
"lint": "eslint src/",
|
|
19
|
+
"test": "vitest",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"thryx",
|
|
24
|
+
"blockchain",
|
|
25
|
+
"ethereum",
|
|
26
|
+
"web3",
|
|
27
|
+
"ai",
|
|
28
|
+
"agents",
|
|
29
|
+
"l2",
|
|
30
|
+
"base"
|
|
31
|
+
],
|
|
32
|
+
"author": "THRYX Team",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/thryx/sdk"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://thryx.mom",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/thryx/sdk/issues"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"viem": "^2.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^20.10.0",
|
|
47
|
+
"tsup": "^8.0.0",
|
|
48
|
+
"typescript": "^5.3.0",
|
|
49
|
+
"vitest": "^1.0.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"viem": "^2.0.0"
|
|
53
|
+
},
|
|
54
|
+
"files": [
|
|
55
|
+
"dist",
|
|
56
|
+
"src"
|
|
57
|
+
],
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18"
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/abis.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract ABIs for Thryx SDK
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const ABIS = {
|
|
6
|
+
ERC20: [
|
|
7
|
+
'function approve(address spender, uint256 amount) returns (bool)',
|
|
8
|
+
'function balanceOf(address account) view returns (uint256)',
|
|
9
|
+
'function decimals() view returns (uint8)',
|
|
10
|
+
'function transfer(address to, uint256 amount) returns (bool)',
|
|
11
|
+
'function transferFrom(address from, address to, uint256 amount) returns (bool)',
|
|
12
|
+
'function allowance(address owner, address spender) view returns (uint256)',
|
|
13
|
+
],
|
|
14
|
+
|
|
15
|
+
AgentRegistry: [
|
|
16
|
+
'function registerAgent(address agentAddress, uint256 dailyBudget, bytes32 permissions, string metadata)',
|
|
17
|
+
'function validateAgent(address agentAddress) view returns (bool)',
|
|
18
|
+
'function hasPermission(address agentAddress, bytes32 permission) view returns (bool)',
|
|
19
|
+
'function recordSpending(address agentAddress, uint256 amount)',
|
|
20
|
+
'function getRemainingBudget(address agentAddress) view returns (uint256)',
|
|
21
|
+
'function deactivateAgent(address agentAddress)',
|
|
22
|
+
'function updateBudget(address agentAddress, uint256 newBudget)',
|
|
23
|
+
'function getAgentCount() view returns (uint256)',
|
|
24
|
+
'function getActiveAgents() view returns (address[])',
|
|
25
|
+
'function agents(address) view returns (address owner, uint256 dailyBudget, uint256 spentToday, uint256 lastResetTimestamp, bytes32 permissions, bool isActive, string metadata)',
|
|
26
|
+
],
|
|
27
|
+
|
|
28
|
+
SimpleAMM: [
|
|
29
|
+
'function addLiquidity(uint256 amountA, uint256 amountB) returns (uint256 liquidity)',
|
|
30
|
+
'function removeLiquidity(uint256 liquidity) returns (uint256 amountA, uint256 amountB)',
|
|
31
|
+
'function swap(address tokenIn, uint256 amountIn, uint256 minAmountOut) returns (uint256 amountOut)',
|
|
32
|
+
'function getAmountOut(address tokenIn, uint256 amountIn) view returns (uint256)',
|
|
33
|
+
'function getPrice() view returns (uint256)',
|
|
34
|
+
'function reserveA() view returns (uint256)',
|
|
35
|
+
'function reserveB() view returns (uint256)',
|
|
36
|
+
'function totalSupply() view returns (uint256)',
|
|
37
|
+
'function balanceOf(address account) view returns (uint256)',
|
|
38
|
+
],
|
|
39
|
+
|
|
40
|
+
AgentOracle: [
|
|
41
|
+
'function submitPrice(bytes32 pair, uint256 price)',
|
|
42
|
+
'function getPrice(bytes32 pair) view returns (uint256 price, uint256 timestamp, bool isStale)',
|
|
43
|
+
'function getActivePairCount() view returns (uint256)',
|
|
44
|
+
'function getSubmissionCount(bytes32 pair) view returns (uint256)',
|
|
45
|
+
'function getSubmitters(bytes32 pair) view returns (address[])',
|
|
46
|
+
],
|
|
47
|
+
|
|
48
|
+
IntentMempool: [
|
|
49
|
+
'function submitIntent(bytes32 goal, bytes constraints, uint256 maxCost, uint256 deadlineSeconds) returns (uint256 intentId)',
|
|
50
|
+
'function fulfillIntent(uint256 intentId, bytes solution, uint256 actualCost)',
|
|
51
|
+
'function cancelIntent(uint256 intentId)',
|
|
52
|
+
'function cleanupExpired()',
|
|
53
|
+
'function getPendingIntents() view returns (uint256[])',
|
|
54
|
+
'function getIntent(uint256 intentId) view returns (tuple(uint256 id, address creator, bytes32 goal, bytes constraints, uint256 maxCost, uint256 deadline, uint8 status, address solver, bytes solution, uint256 actualCost))',
|
|
55
|
+
],
|
|
56
|
+
|
|
57
|
+
StablecoinGas: [
|
|
58
|
+
'function depositGas(uint256 amount)',
|
|
59
|
+
'function payForGas(address agent, uint256 gasUsed) returns (uint256)',
|
|
60
|
+
'function withdrawGas(uint256 amount)',
|
|
61
|
+
'function distributeFees()',
|
|
62
|
+
'function getGasBalance(address account) view returns (uint256)',
|
|
63
|
+
'function gasPriceUsdc() view returns (uint256)',
|
|
64
|
+
'function totalFeesCollected() view returns (uint256)',
|
|
65
|
+
'function humanFeesAccrued() view returns (uint256)',
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default ABIS;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @thryx/sdk
|
|
3
|
+
* TypeScript SDK for THRYX - AI-Native Blockchain
|
|
4
|
+
* Chain ID: 77777
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { ThryxSDK, THRYX_CHAIN } from '@thryx/sdk';
|
|
9
|
+
*
|
|
10
|
+
* const sdk = new ThryxSDK({
|
|
11
|
+
* rpcUrl: 'https://rpc.thryx.mom',
|
|
12
|
+
* privateKey: '0x...'
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* // Get block number
|
|
16
|
+
* const blockNumber = await sdk.getBlockNumber();
|
|
17
|
+
*
|
|
18
|
+
* // Swap tokens
|
|
19
|
+
* await sdk.swap('0xUSDC', '0xWETH', 100n * 10n**6n, 0n);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import {
|
|
24
|
+
createPublicClient,
|
|
25
|
+
createWalletClient,
|
|
26
|
+
http,
|
|
27
|
+
parseAbi,
|
|
28
|
+
formatEther,
|
|
29
|
+
parseEther,
|
|
30
|
+
type PublicClient,
|
|
31
|
+
type WalletClient,
|
|
32
|
+
type Address,
|
|
33
|
+
type Hash,
|
|
34
|
+
type Chain,
|
|
35
|
+
} from 'viem';
|
|
36
|
+
import { privateKeyToAccount, type PrivateKeyAccount } from 'viem/accounts';
|
|
37
|
+
|
|
38
|
+
// ==================== Chain Configuration ====================
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* THRYX Mainnet chain configuration
|
|
42
|
+
*/
|
|
43
|
+
export const THRYX_CHAIN: Chain = {
|
|
44
|
+
id: 77777,
|
|
45
|
+
name: 'THRYX Mainnet',
|
|
46
|
+
nativeCurrency: {
|
|
47
|
+
decimals: 18,
|
|
48
|
+
name: 'Ether',
|
|
49
|
+
symbol: 'ETH',
|
|
50
|
+
},
|
|
51
|
+
rpcUrls: {
|
|
52
|
+
default: { http: ['https://rpc.thryx.mom'] },
|
|
53
|
+
public: { http: ['https://rpc.thryx.mom'] },
|
|
54
|
+
},
|
|
55
|
+
blockExplorers: {
|
|
56
|
+
default: { name: 'THRYX Explorer', url: 'https://explorer.thryx.mom' },
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Base Mainnet (L1 for THRYX)
|
|
62
|
+
*/
|
|
63
|
+
export const BASE_CHAIN: Chain = {
|
|
64
|
+
id: 8453,
|
|
65
|
+
name: 'Base',
|
|
66
|
+
nativeCurrency: {
|
|
67
|
+
decimals: 18,
|
|
68
|
+
name: 'Ether',
|
|
69
|
+
symbol: 'ETH',
|
|
70
|
+
},
|
|
71
|
+
rpcUrls: {
|
|
72
|
+
default: { http: ['https://mainnet.base.org'] },
|
|
73
|
+
public: { http: ['https://mainnet.base.org'] },
|
|
74
|
+
},
|
|
75
|
+
blockExplorers: {
|
|
76
|
+
default: { name: 'Basescan', url: 'https://basescan.org' },
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// ==================== ABIs ====================
|
|
81
|
+
|
|
82
|
+
export const ERC20_ABI = parseAbi([
|
|
83
|
+
'function name() view returns (string)',
|
|
84
|
+
'function symbol() view returns (string)',
|
|
85
|
+
'function decimals() view returns (uint8)',
|
|
86
|
+
'function totalSupply() view returns (uint256)',
|
|
87
|
+
'function balanceOf(address owner) view returns (uint256)',
|
|
88
|
+
'function allowance(address owner, address spender) view returns (uint256)',
|
|
89
|
+
'function approve(address spender, uint256 amount) returns (bool)',
|
|
90
|
+
'function transfer(address to, uint256 amount) returns (bool)',
|
|
91
|
+
'function transferFrom(address from, address to, uint256 amount) returns (bool)',
|
|
92
|
+
'event Transfer(address indexed from, address indexed to, uint256 value)',
|
|
93
|
+
'event Approval(address indexed owner, address indexed spender, uint256 value)',
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
export const AMM_ABI = parseAbi([
|
|
97
|
+
'function tokenA() view returns (address)',
|
|
98
|
+
'function tokenB() view returns (address)',
|
|
99
|
+
'function reserveA() view returns (uint256)',
|
|
100
|
+
'function reserveB() view returns (uint256)',
|
|
101
|
+
'function getPrice() view returns (uint256)',
|
|
102
|
+
'function getAmountOut(address tokenIn, uint256 amountIn) view returns (uint256)',
|
|
103
|
+
'function swap(address tokenIn, uint256 amountIn, uint256 minAmountOut) returns (uint256)',
|
|
104
|
+
'function addLiquidity(uint256 amountA, uint256 amountB) returns (uint256)',
|
|
105
|
+
'function removeLiquidity(uint256 lpAmount) returns (uint256, uint256)',
|
|
106
|
+
'function balanceOf(address owner) view returns (uint256)',
|
|
107
|
+
'event Swap(address indexed user, address tokenIn, uint256 amountIn, uint256 amountOut)',
|
|
108
|
+
'event LiquidityAdded(address indexed user, uint256 amountA, uint256 amountB, uint256 liquidity)',
|
|
109
|
+
]);
|
|
110
|
+
|
|
111
|
+
export const ORACLE_ABI = parseAbi([
|
|
112
|
+
'function getPrice(bytes32 pair) view returns (uint256 price, uint256 timestamp, bool isStale)',
|
|
113
|
+
'function submitPrice(bytes32 pair, uint256 price)',
|
|
114
|
+
'function getSubmissionCount(bytes32 pair) view returns (uint256)',
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
export const AGENT_REGISTRY_ABI = parseAbi([
|
|
118
|
+
'function getAgentCount() view returns (uint256)',
|
|
119
|
+
'function getActiveAgents() view returns (address[])',
|
|
120
|
+
'function validateAgent(address agent) view returns (bool)',
|
|
121
|
+
'function getRemainingBudget(address agent) view returns (uint256)',
|
|
122
|
+
]);
|
|
123
|
+
|
|
124
|
+
export const WELCOME_BONUS_ABI = parseAbi([
|
|
125
|
+
'function claim()',
|
|
126
|
+
'function claimFor(address beneficiary)',
|
|
127
|
+
'function canClaim(address user) view returns (bool canClaimResult, uint256 amount)',
|
|
128
|
+
'function claimed(address user) view returns (bool)',
|
|
129
|
+
'function bonusAmount() view returns (uint256)',
|
|
130
|
+
'function totalClaims() view returns (uint256)',
|
|
131
|
+
]);
|
|
132
|
+
|
|
133
|
+
export const THRYX_TOKEN_ABI = parseAbi([
|
|
134
|
+
'function name() view returns (string)',
|
|
135
|
+
'function symbol() view returns (string)',
|
|
136
|
+
'function decimals() view returns (uint8)',
|
|
137
|
+
'function totalSupply() view returns (uint256)',
|
|
138
|
+
'function balanceOf(address owner) view returns (uint256)',
|
|
139
|
+
'function transfer(address to, uint256 amount) returns (bool)',
|
|
140
|
+
'function approve(address spender, uint256 amount) returns (bool)',
|
|
141
|
+
]);
|
|
142
|
+
|
|
143
|
+
// ==================== Types ====================
|
|
144
|
+
|
|
145
|
+
export interface ThryxSDKConfig {
|
|
146
|
+
rpcUrl?: string;
|
|
147
|
+
privateKey?: string;
|
|
148
|
+
contracts?: ContractAddresses;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface ContractAddresses {
|
|
152
|
+
usdc?: Address;
|
|
153
|
+
weth?: Address;
|
|
154
|
+
amm?: Address;
|
|
155
|
+
oracle?: Address;
|
|
156
|
+
registry?: Address;
|
|
157
|
+
thryxToken?: Address;
|
|
158
|
+
welcomeBonus?: Address;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface PoolState {
|
|
162
|
+
reserveA: bigint;
|
|
163
|
+
reserveB: bigint;
|
|
164
|
+
price: bigint;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface PriceData {
|
|
168
|
+
price: bigint;
|
|
169
|
+
timestamp: number;
|
|
170
|
+
isStale: boolean;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ==================== Default Contract Addresses ====================
|
|
174
|
+
|
|
175
|
+
export const DEFAULT_CONTRACTS: ContractAddresses = {
|
|
176
|
+
usdc: '0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154',
|
|
177
|
+
weth: '0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575',
|
|
178
|
+
amm: '0x2bdCC0de6bE1f7D2ee689a0342D76F52E8EFABa3',
|
|
179
|
+
oracle: '0x7969c5eD335650692Bc04293B07F5BF2e7A673C0',
|
|
180
|
+
registry: '0xCD8a1C3ba11CF5ECfa6267617243239504a98d90',
|
|
181
|
+
thryxToken: '0x2B0d36FACD61B71CC05ab8F3D2355ec3631C0dd5',
|
|
182
|
+
welcomeBonus: '0xCace1b78160AE76398F486c8a18044da0d66d86D',
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// ==================== SDK Class ====================
|
|
186
|
+
|
|
187
|
+
export class ThryxSDK {
|
|
188
|
+
public readonly publicClient: PublicClient;
|
|
189
|
+
public readonly walletClient: WalletClient | null;
|
|
190
|
+
public readonly account: PrivateKeyAccount | null;
|
|
191
|
+
public readonly contracts: ContractAddresses;
|
|
192
|
+
public readonly chainId = 77777;
|
|
193
|
+
|
|
194
|
+
constructor(config: ThryxSDKConfig = {}) {
|
|
195
|
+
const rpcUrl = config.rpcUrl || 'http://localhost:8545';
|
|
196
|
+
this.contracts = { ...DEFAULT_CONTRACTS, ...config.contracts };
|
|
197
|
+
|
|
198
|
+
// Create public client (read-only)
|
|
199
|
+
this.publicClient = createPublicClient({
|
|
200
|
+
chain: THRYX_CHAIN,
|
|
201
|
+
transport: http(rpcUrl),
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Create wallet client if private key provided
|
|
205
|
+
if (config.privateKey) {
|
|
206
|
+
this.account = privateKeyToAccount(config.privateKey as `0x${string}`);
|
|
207
|
+
this.walletClient = createWalletClient({
|
|
208
|
+
account: this.account,
|
|
209
|
+
chain: THRYX_CHAIN,
|
|
210
|
+
transport: http(rpcUrl),
|
|
211
|
+
});
|
|
212
|
+
} else {
|
|
213
|
+
this.account = null;
|
|
214
|
+
this.walletClient = null;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ==================== Connection ====================
|
|
219
|
+
|
|
220
|
+
get address(): Address | null {
|
|
221
|
+
return this.account?.address || null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async getBlockNumber(): Promise<bigint> {
|
|
225
|
+
return this.publicClient.getBlockNumber();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async getBalance(address?: Address): Promise<bigint> {
|
|
229
|
+
const addr = address || this.address;
|
|
230
|
+
if (!addr) throw new Error('No address provided');
|
|
231
|
+
return this.publicClient.getBalance({ address: addr });
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async getChainId(): Promise<number> {
|
|
235
|
+
return this.publicClient.getChainId();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// ==================== Token Operations ====================
|
|
239
|
+
|
|
240
|
+
async getTokenBalance(tokenAddress: Address, owner?: Address): Promise<bigint> {
|
|
241
|
+
const addr = owner || this.address;
|
|
242
|
+
if (!addr) throw new Error('No address provided');
|
|
243
|
+
|
|
244
|
+
return this.publicClient.readContract({
|
|
245
|
+
address: tokenAddress,
|
|
246
|
+
abi: ERC20_ABI,
|
|
247
|
+
functionName: 'balanceOf',
|
|
248
|
+
args: [addr],
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async getUsdcBalance(owner?: Address): Promise<bigint> {
|
|
253
|
+
if (!this.contracts.usdc) throw new Error('USDC address not configured');
|
|
254
|
+
return this.getTokenBalance(this.contracts.usdc, owner);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async getWethBalance(owner?: Address): Promise<bigint> {
|
|
258
|
+
if (!this.contracts.weth) throw new Error('WETH address not configured');
|
|
259
|
+
return this.getTokenBalance(this.contracts.weth, owner);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async getThryxBalance(owner?: Address): Promise<bigint> {
|
|
263
|
+
if (!this.contracts.thryxToken) throw new Error('THRYX Token address not configured');
|
|
264
|
+
return this.getTokenBalance(this.contracts.thryxToken, owner);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async approve(tokenAddress: Address, spender: Address, amount: bigint): Promise<Hash> {
|
|
268
|
+
if (!this.walletClient || !this.account) throw new Error('Wallet not connected');
|
|
269
|
+
|
|
270
|
+
return this.walletClient.writeContract({
|
|
271
|
+
address: tokenAddress,
|
|
272
|
+
abi: ERC20_ABI,
|
|
273
|
+
functionName: 'approve',
|
|
274
|
+
args: [spender, amount],
|
|
275
|
+
chain: THRYX_CHAIN,
|
|
276
|
+
account: this.account,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// ==================== AMM Operations ====================
|
|
281
|
+
|
|
282
|
+
async getPoolState(): Promise<PoolState> {
|
|
283
|
+
if (!this.contracts.amm) throw new Error('AMM address not configured');
|
|
284
|
+
|
|
285
|
+
const [reserveA, reserveB, price] = await Promise.all([
|
|
286
|
+
this.publicClient.readContract({
|
|
287
|
+
address: this.contracts.amm,
|
|
288
|
+
abi: AMM_ABI,
|
|
289
|
+
functionName: 'reserveA',
|
|
290
|
+
}),
|
|
291
|
+
this.publicClient.readContract({
|
|
292
|
+
address: this.contracts.amm,
|
|
293
|
+
abi: AMM_ABI,
|
|
294
|
+
functionName: 'reserveB',
|
|
295
|
+
}),
|
|
296
|
+
this.publicClient.readContract({
|
|
297
|
+
address: this.contracts.amm,
|
|
298
|
+
abi: AMM_ABI,
|
|
299
|
+
functionName: 'getPrice',
|
|
300
|
+
}),
|
|
301
|
+
]);
|
|
302
|
+
|
|
303
|
+
return { reserveA, reserveB, price };
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async getAmountOut(tokenIn: Address, amountIn: bigint): Promise<bigint> {
|
|
307
|
+
if (!this.contracts.amm) throw new Error('AMM address not configured');
|
|
308
|
+
|
|
309
|
+
return this.publicClient.readContract({
|
|
310
|
+
address: this.contracts.amm,
|
|
311
|
+
abi: AMM_ABI,
|
|
312
|
+
functionName: 'getAmountOut',
|
|
313
|
+
args: [tokenIn, amountIn],
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async swap(tokenIn: Address, amountIn: bigint, minAmountOut: bigint): Promise<Hash> {
|
|
318
|
+
if (!this.walletClient || !this.account) throw new Error('Wallet not connected');
|
|
319
|
+
if (!this.contracts.amm) throw new Error('AMM address not configured');
|
|
320
|
+
|
|
321
|
+
// First approve
|
|
322
|
+
await this.approve(tokenIn, this.contracts.amm, amountIn);
|
|
323
|
+
|
|
324
|
+
// Then swap
|
|
325
|
+
return this.walletClient.writeContract({
|
|
326
|
+
address: this.contracts.amm,
|
|
327
|
+
abi: AMM_ABI,
|
|
328
|
+
functionName: 'swap',
|
|
329
|
+
args: [tokenIn, amountIn, minAmountOut],
|
|
330
|
+
chain: THRYX_CHAIN,
|
|
331
|
+
account: this.account,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// ==================== Oracle Operations ====================
|
|
336
|
+
|
|
337
|
+
async getPrice(pair: string): Promise<PriceData> {
|
|
338
|
+
if (!this.contracts.oracle) throw new Error('Oracle address not configured');
|
|
339
|
+
|
|
340
|
+
const pairHash = this.hashPair(pair);
|
|
341
|
+
const [price, timestamp, isStale] = await this.publicClient.readContract({
|
|
342
|
+
address: this.contracts.oracle,
|
|
343
|
+
abi: ORACLE_ABI,
|
|
344
|
+
functionName: 'getPrice',
|
|
345
|
+
args: [pairHash],
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
return {
|
|
349
|
+
price,
|
|
350
|
+
timestamp: Number(timestamp),
|
|
351
|
+
isStale,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// ==================== Welcome Bonus ====================
|
|
356
|
+
|
|
357
|
+
async canClaimBonus(address?: Address): Promise<{ canClaim: boolean; amount: bigint }> {
|
|
358
|
+
if (!this.contracts.welcomeBonus) throw new Error('WelcomeBonus address not configured');
|
|
359
|
+
const addr = address || this.address;
|
|
360
|
+
if (!addr) throw new Error('No address provided');
|
|
361
|
+
|
|
362
|
+
const [canClaim, amount] = await this.publicClient.readContract({
|
|
363
|
+
address: this.contracts.welcomeBonus,
|
|
364
|
+
abi: WELCOME_BONUS_ABI,
|
|
365
|
+
functionName: 'canClaim',
|
|
366
|
+
args: [addr],
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
return { canClaim, amount };
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
async claimBonus(): Promise<Hash> {
|
|
373
|
+
if (!this.walletClient || !this.account) throw new Error('Wallet not connected');
|
|
374
|
+
if (!this.contracts.welcomeBonus) throw new Error('WelcomeBonus address not configured');
|
|
375
|
+
|
|
376
|
+
return this.walletClient.writeContract({
|
|
377
|
+
address: this.contracts.welcomeBonus,
|
|
378
|
+
abi: WELCOME_BONUS_ABI,
|
|
379
|
+
functionName: 'claim',
|
|
380
|
+
chain: THRYX_CHAIN,
|
|
381
|
+
account: this.account,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// ==================== Agent Registry ====================
|
|
386
|
+
|
|
387
|
+
async getAgentCount(): Promise<bigint> {
|
|
388
|
+
if (!this.contracts.registry) throw new Error('Registry address not configured');
|
|
389
|
+
|
|
390
|
+
return this.publicClient.readContract({
|
|
391
|
+
address: this.contracts.registry,
|
|
392
|
+
abi: AGENT_REGISTRY_ABI,
|
|
393
|
+
functionName: 'getAgentCount',
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
async getActiveAgents(): Promise<readonly Address[]> {
|
|
398
|
+
if (!this.contracts.registry) throw new Error('Registry address not configured');
|
|
399
|
+
|
|
400
|
+
return this.publicClient.readContract({
|
|
401
|
+
address: this.contracts.registry,
|
|
402
|
+
abi: AGENT_REGISTRY_ABI,
|
|
403
|
+
functionName: 'getActiveAgents',
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
async isAgentValid(agent: Address): Promise<boolean> {
|
|
408
|
+
if (!this.contracts.registry) throw new Error('Registry address not configured');
|
|
409
|
+
|
|
410
|
+
return this.publicClient.readContract({
|
|
411
|
+
address: this.contracts.registry,
|
|
412
|
+
abi: AGENT_REGISTRY_ABI,
|
|
413
|
+
functionName: 'validateAgent',
|
|
414
|
+
args: [agent],
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// ==================== Utilities ====================
|
|
419
|
+
|
|
420
|
+
private hashPair(pair: string): `0x${string}` {
|
|
421
|
+
// Simple keccak256 hash
|
|
422
|
+
const encoder = new TextEncoder();
|
|
423
|
+
const data = encoder.encode(pair);
|
|
424
|
+
// In a real implementation, use proper keccak256
|
|
425
|
+
return `0x${Buffer.from(data).toString('hex').padEnd(64, '0')}` as `0x${string}`;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
formatEther(wei: bigint): string {
|
|
429
|
+
return formatEther(wei);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
parseEther(ether: string): bigint {
|
|
433
|
+
return parseEther(ether);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ==================== Exports ====================
|
|
438
|
+
|
|
439
|
+
export default ThryxSDK;
|
|
440
|
+
export { formatEther, parseEther } from 'viem';
|