@thryx/sdk 1.0.0 → 1.1.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 CHANGED
@@ -544,6 +544,15 @@ interface PriceData {
544
544
  timestamp: number;
545
545
  isStale: boolean;
546
546
  }
547
+ /**
548
+ * Bridge wallet address on Base mainnet
549
+ * Send ETH to this address on Base to receive ETH on THRYX
550
+ */
551
+ declare const BRIDGE_WALLET: Address;
552
+ /**
553
+ * Base USDC contract address
554
+ */
555
+ declare const BASE_USDC: Address;
547
556
  declare const DEFAULT_CONTRACTS: ContractAddresses;
548
557
  declare class ThryxSDK {
549
558
  readonly publicClient: PublicClient;
@@ -573,9 +582,68 @@ declare class ThryxSDK {
573
582
  getAgentCount(): Promise<bigint>;
574
583
  getActiveAgents(): Promise<readonly Address[]>;
575
584
  isAgentValid(agent: Address): Promise<boolean>;
585
+ /**
586
+ * Get a bridge client for Base -> THRYX bridging
587
+ * @param baseRpcUrl - RPC URL for Base mainnet
588
+ * @param privateKey - Private key for signing transactions on Base
589
+ */
590
+ createBridgeClient(baseRpcUrl?: string, privateKey?: string): BridgeClient;
576
591
  private hashPair;
577
592
  formatEther(wei: bigint): string;
578
593
  parseEther(ether: string): bigint;
579
594
  }
595
+ interface BridgeResult {
596
+ success: boolean;
597
+ txHash?: Hash;
598
+ error?: string;
599
+ amount?: string;
600
+ }
601
+ /**
602
+ * Bridge client for Base -> THRYX transfers
603
+ *
604
+ * @example
605
+ * ```typescript
606
+ * const bridge = new BridgeClient('https://mainnet.base.org', '0xprivatekey');
607
+ *
608
+ * // Bridge 0.01 ETH from Base to THRYX
609
+ * const result = await bridge.bridgeETH('0.01');
610
+ * console.log('Bridge tx:', result.txHash);
611
+ * ```
612
+ */
613
+ declare class BridgeClient {
614
+ readonly publicClient: PublicClient;
615
+ readonly walletClient: WalletClient | null;
616
+ readonly account: PrivateKeyAccount | null;
617
+ constructor(baseRpcUrl?: string, privateKey?: string);
618
+ get address(): Address | null;
619
+ /**
620
+ * Get ETH balance on Base
621
+ */
622
+ getBaseBalance(address?: Address): Promise<bigint>;
623
+ /**
624
+ * Get USDC balance on Base
625
+ */
626
+ getBaseUsdcBalance(address?: Address): Promise<bigint>;
627
+ /**
628
+ * Bridge ETH from Base to THRYX
629
+ * Sends ETH to the bridge wallet on Base, which triggers automatic minting on THRYX
630
+ *
631
+ * @param amount - Amount of ETH to bridge (e.g., "0.01")
632
+ * @returns Bridge result with transaction hash
633
+ */
634
+ bridgeETH(amount: string): Promise<BridgeResult>;
635
+ /**
636
+ * Bridge USDC from Base to THRYX
637
+ * Sends USDC to the bridge wallet on Base, which triggers automatic minting on THRYX
638
+ *
639
+ * @param amount - Amount of USDC to bridge (e.g., "100" for 100 USDC)
640
+ * @returns Bridge result with transaction hash
641
+ */
642
+ bridgeUSDC(amount: string): Promise<BridgeResult>;
643
+ /**
644
+ * Get the bridge wallet address
645
+ */
646
+ getBridgeWallet(): Address;
647
+ }
580
648
 
581
- export { AGENT_REGISTRY_ABI, AMM_ABI, BASE_CHAIN, type ContractAddresses, DEFAULT_CONTRACTS, ERC20_ABI, ORACLE_ABI, type PoolState, type PriceData, THRYX_CHAIN, THRYX_TOKEN_ABI, ThryxSDK, type ThryxSDKConfig, WELCOME_BONUS_ABI, ThryxSDK as default };
649
+ export { AGENT_REGISTRY_ABI, AMM_ABI, BASE_CHAIN, BASE_USDC, BRIDGE_WALLET, BridgeClient, type BridgeResult, type ContractAddresses, DEFAULT_CONTRACTS, ERC20_ABI, ORACLE_ABI, type PoolState, type PriceData, THRYX_CHAIN, THRYX_TOKEN_ABI, ThryxSDK, type ThryxSDKConfig, WELCOME_BONUS_ABI, ThryxSDK as default };
package/dist/index.d.ts CHANGED
@@ -544,6 +544,15 @@ interface PriceData {
544
544
  timestamp: number;
545
545
  isStale: boolean;
546
546
  }
547
+ /**
548
+ * Bridge wallet address on Base mainnet
549
+ * Send ETH to this address on Base to receive ETH on THRYX
550
+ */
551
+ declare const BRIDGE_WALLET: Address;
552
+ /**
553
+ * Base USDC contract address
554
+ */
555
+ declare const BASE_USDC: Address;
547
556
  declare const DEFAULT_CONTRACTS: ContractAddresses;
548
557
  declare class ThryxSDK {
549
558
  readonly publicClient: PublicClient;
@@ -573,9 +582,68 @@ declare class ThryxSDK {
573
582
  getAgentCount(): Promise<bigint>;
574
583
  getActiveAgents(): Promise<readonly Address[]>;
575
584
  isAgentValid(agent: Address): Promise<boolean>;
585
+ /**
586
+ * Get a bridge client for Base -> THRYX bridging
587
+ * @param baseRpcUrl - RPC URL for Base mainnet
588
+ * @param privateKey - Private key for signing transactions on Base
589
+ */
590
+ createBridgeClient(baseRpcUrl?: string, privateKey?: string): BridgeClient;
576
591
  private hashPair;
577
592
  formatEther(wei: bigint): string;
578
593
  parseEther(ether: string): bigint;
579
594
  }
595
+ interface BridgeResult {
596
+ success: boolean;
597
+ txHash?: Hash;
598
+ error?: string;
599
+ amount?: string;
600
+ }
601
+ /**
602
+ * Bridge client for Base -> THRYX transfers
603
+ *
604
+ * @example
605
+ * ```typescript
606
+ * const bridge = new BridgeClient('https://mainnet.base.org', '0xprivatekey');
607
+ *
608
+ * // Bridge 0.01 ETH from Base to THRYX
609
+ * const result = await bridge.bridgeETH('0.01');
610
+ * console.log('Bridge tx:', result.txHash);
611
+ * ```
612
+ */
613
+ declare class BridgeClient {
614
+ readonly publicClient: PublicClient;
615
+ readonly walletClient: WalletClient | null;
616
+ readonly account: PrivateKeyAccount | null;
617
+ constructor(baseRpcUrl?: string, privateKey?: string);
618
+ get address(): Address | null;
619
+ /**
620
+ * Get ETH balance on Base
621
+ */
622
+ getBaseBalance(address?: Address): Promise<bigint>;
623
+ /**
624
+ * Get USDC balance on Base
625
+ */
626
+ getBaseUsdcBalance(address?: Address): Promise<bigint>;
627
+ /**
628
+ * Bridge ETH from Base to THRYX
629
+ * Sends ETH to the bridge wallet on Base, which triggers automatic minting on THRYX
630
+ *
631
+ * @param amount - Amount of ETH to bridge (e.g., "0.01")
632
+ * @returns Bridge result with transaction hash
633
+ */
634
+ bridgeETH(amount: string): Promise<BridgeResult>;
635
+ /**
636
+ * Bridge USDC from Base to THRYX
637
+ * Sends USDC to the bridge wallet on Base, which triggers automatic minting on THRYX
638
+ *
639
+ * @param amount - Amount of USDC to bridge (e.g., "100" for 100 USDC)
640
+ * @returns Bridge result with transaction hash
641
+ */
642
+ bridgeUSDC(amount: string): Promise<BridgeResult>;
643
+ /**
644
+ * Get the bridge wallet address
645
+ */
646
+ getBridgeWallet(): Address;
647
+ }
580
648
 
581
- export { AGENT_REGISTRY_ABI, AMM_ABI, BASE_CHAIN, type ContractAddresses, DEFAULT_CONTRACTS, ERC20_ABI, ORACLE_ABI, type PoolState, type PriceData, THRYX_CHAIN, THRYX_TOKEN_ABI, ThryxSDK, type ThryxSDKConfig, WELCOME_BONUS_ABI, ThryxSDK as default };
649
+ export { AGENT_REGISTRY_ABI, AMM_ABI, BASE_CHAIN, BASE_USDC, BRIDGE_WALLET, BridgeClient, type BridgeResult, type ContractAddresses, DEFAULT_CONTRACTS, ERC20_ABI, ORACLE_ABI, type PoolState, type PriceData, THRYX_CHAIN, THRYX_TOKEN_ABI, ThryxSDK, type ThryxSDKConfig, WELCOME_BONUS_ABI, ThryxSDK as default };
package/dist/index.js CHANGED
@@ -23,6 +23,9 @@ __export(index_exports, {
23
23
  AGENT_REGISTRY_ABI: () => AGENT_REGISTRY_ABI,
24
24
  AMM_ABI: () => AMM_ABI,
25
25
  BASE_CHAIN: () => BASE_CHAIN,
26
+ BASE_USDC: () => BASE_USDC,
27
+ BRIDGE_WALLET: () => BRIDGE_WALLET,
28
+ BridgeClient: () => BridgeClient,
26
29
  DEFAULT_CONTRACTS: () => DEFAULT_CONTRACTS,
27
30
  ERC20_ABI: () => ERC20_ABI,
28
31
  ORACLE_ABI: () => ORACLE_ABI,
@@ -125,6 +128,8 @@ var THRYX_TOKEN_ABI = (0, import_viem.parseAbi)([
125
128
  "function transfer(address to, uint256 amount) returns (bool)",
126
129
  "function approve(address spender, uint256 amount) returns (bool)"
127
130
  ]);
131
+ var BRIDGE_WALLET = "0x338304e35841d2Fa6849EF855f6beBD8988C65B8";
132
+ var BASE_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
128
133
  var DEFAULT_CONTRACTS = {
129
134
  usdc: "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154",
130
135
  weth: "0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575",
@@ -314,6 +319,15 @@ var ThryxSDK = class {
314
319
  args: [agent]
315
320
  });
316
321
  }
322
+ // ==================== Bridge Operations ====================
323
+ /**
324
+ * Get a bridge client for Base -> THRYX bridging
325
+ * @param baseRpcUrl - RPC URL for Base mainnet
326
+ * @param privateKey - Private key for signing transactions on Base
327
+ */
328
+ createBridgeClient(baseRpcUrl = "https://mainnet.base.org", privateKey) {
329
+ return new BridgeClient(baseRpcUrl, privateKey);
330
+ }
317
331
  // ==================== Utilities ====================
318
332
  hashPair(pair) {
319
333
  const encoder = new TextEncoder();
@@ -327,12 +341,142 @@ var ThryxSDK = class {
327
341
  return (0, import_viem.parseEther)(ether);
328
342
  }
329
343
  };
344
+ var BridgeClient = class {
345
+ constructor(baseRpcUrl = "https://mainnet.base.org", privateKey) {
346
+ this.publicClient = (0, import_viem.createPublicClient)({
347
+ chain: BASE_CHAIN,
348
+ transport: (0, import_viem.http)(baseRpcUrl)
349
+ });
350
+ if (privateKey) {
351
+ this.account = (0, import_accounts.privateKeyToAccount)(privateKey);
352
+ this.walletClient = (0, import_viem.createWalletClient)({
353
+ account: this.account,
354
+ chain: BASE_CHAIN,
355
+ transport: (0, import_viem.http)(baseRpcUrl)
356
+ });
357
+ } else {
358
+ this.account = null;
359
+ this.walletClient = null;
360
+ }
361
+ }
362
+ get address() {
363
+ return this.account?.address || null;
364
+ }
365
+ /**
366
+ * Get ETH balance on Base
367
+ */
368
+ async getBaseBalance(address) {
369
+ const addr = address || this.address;
370
+ if (!addr) throw new Error("No address provided");
371
+ return this.publicClient.getBalance({ address: addr });
372
+ }
373
+ /**
374
+ * Get USDC balance on Base
375
+ */
376
+ async getBaseUsdcBalance(address) {
377
+ const addr = address || this.address;
378
+ if (!addr) throw new Error("No address provided");
379
+ return this.publicClient.readContract({
380
+ address: BASE_USDC,
381
+ abi: ERC20_ABI,
382
+ functionName: "balanceOf",
383
+ args: [addr]
384
+ });
385
+ }
386
+ /**
387
+ * Bridge ETH from Base to THRYX
388
+ * Sends ETH to the bridge wallet on Base, which triggers automatic minting on THRYX
389
+ *
390
+ * @param amount - Amount of ETH to bridge (e.g., "0.01")
391
+ * @returns Bridge result with transaction hash
392
+ */
393
+ async bridgeETH(amount) {
394
+ if (!this.walletClient || !this.account) {
395
+ return { success: false, error: "Wallet not connected - provide privateKey in constructor" };
396
+ }
397
+ try {
398
+ const amountWei = (0, import_viem.parseEther)(amount);
399
+ const balance = await this.getBaseBalance();
400
+ if (balance < amountWei) {
401
+ return {
402
+ success: false,
403
+ error: `Insufficient balance. Have ${(0, import_viem.formatEther)(balance)} ETH, need ${amount} ETH`
404
+ };
405
+ }
406
+ const txHash = await this.walletClient.sendTransaction({
407
+ to: BRIDGE_WALLET,
408
+ value: amountWei,
409
+ chain: BASE_CHAIN,
410
+ account: this.account
411
+ });
412
+ return {
413
+ success: true,
414
+ txHash,
415
+ amount
416
+ };
417
+ } catch (error) {
418
+ return {
419
+ success: false,
420
+ error: error instanceof Error ? error.message : String(error)
421
+ };
422
+ }
423
+ }
424
+ /**
425
+ * Bridge USDC from Base to THRYX
426
+ * Sends USDC to the bridge wallet on Base, which triggers automatic minting on THRYX
427
+ *
428
+ * @param amount - Amount of USDC to bridge (e.g., "100" for 100 USDC)
429
+ * @returns Bridge result with transaction hash
430
+ */
431
+ async bridgeUSDC(amount) {
432
+ if (!this.walletClient || !this.account) {
433
+ return { success: false, error: "Wallet not connected - provide privateKey in constructor" };
434
+ }
435
+ try {
436
+ const amountUnits = BigInt(Math.floor(parseFloat(amount) * 1e6));
437
+ const balance = await this.getBaseUsdcBalance();
438
+ if (balance < amountUnits) {
439
+ return {
440
+ success: false,
441
+ error: `Insufficient USDC balance. Have ${Number(balance) / 1e6} USDC, need ${amount} USDC`
442
+ };
443
+ }
444
+ const txHash = await this.walletClient.writeContract({
445
+ address: BASE_USDC,
446
+ abi: ERC20_ABI,
447
+ functionName: "transfer",
448
+ args: [BRIDGE_WALLET, amountUnits],
449
+ chain: BASE_CHAIN,
450
+ account: this.account
451
+ });
452
+ return {
453
+ success: true,
454
+ txHash,
455
+ amount
456
+ };
457
+ } catch (error) {
458
+ return {
459
+ success: false,
460
+ error: error instanceof Error ? error.message : String(error)
461
+ };
462
+ }
463
+ }
464
+ /**
465
+ * Get the bridge wallet address
466
+ */
467
+ getBridgeWallet() {
468
+ return BRIDGE_WALLET;
469
+ }
470
+ };
330
471
  var index_default = ThryxSDK;
331
472
  // Annotate the CommonJS export names for ESM import in node:
332
473
  0 && (module.exports = {
333
474
  AGENT_REGISTRY_ABI,
334
475
  AMM_ABI,
335
476
  BASE_CHAIN,
477
+ BASE_USDC,
478
+ BRIDGE_WALLET,
479
+ BridgeClient,
336
480
  DEFAULT_CONTRACTS,
337
481
  ERC20_ABI,
338
482
  ORACLE_ABI,
package/dist/index.mjs CHANGED
@@ -96,6 +96,8 @@ var THRYX_TOKEN_ABI = parseAbi([
96
96
  "function transfer(address to, uint256 amount) returns (bool)",
97
97
  "function approve(address spender, uint256 amount) returns (bool)"
98
98
  ]);
99
+ var BRIDGE_WALLET = "0x338304e35841d2Fa6849EF855f6beBD8988C65B8";
100
+ var BASE_USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
99
101
  var DEFAULT_CONTRACTS = {
100
102
  usdc: "0x5f3f1dBD7B74C6B46e8c44f98792A1dAf8d69154",
101
103
  weth: "0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575",
@@ -285,6 +287,15 @@ var ThryxSDK = class {
285
287
  args: [agent]
286
288
  });
287
289
  }
290
+ // ==================== Bridge Operations ====================
291
+ /**
292
+ * Get a bridge client for Base -> THRYX bridging
293
+ * @param baseRpcUrl - RPC URL for Base mainnet
294
+ * @param privateKey - Private key for signing transactions on Base
295
+ */
296
+ createBridgeClient(baseRpcUrl = "https://mainnet.base.org", privateKey) {
297
+ return new BridgeClient(baseRpcUrl, privateKey);
298
+ }
288
299
  // ==================== Utilities ====================
289
300
  hashPair(pair) {
290
301
  const encoder = new TextEncoder();
@@ -298,11 +309,141 @@ var ThryxSDK = class {
298
309
  return parseEther(ether);
299
310
  }
300
311
  };
312
+ var BridgeClient = class {
313
+ constructor(baseRpcUrl = "https://mainnet.base.org", privateKey) {
314
+ this.publicClient = createPublicClient({
315
+ chain: BASE_CHAIN,
316
+ transport: http(baseRpcUrl)
317
+ });
318
+ if (privateKey) {
319
+ this.account = privateKeyToAccount(privateKey);
320
+ this.walletClient = createWalletClient({
321
+ account: this.account,
322
+ chain: BASE_CHAIN,
323
+ transport: http(baseRpcUrl)
324
+ });
325
+ } else {
326
+ this.account = null;
327
+ this.walletClient = null;
328
+ }
329
+ }
330
+ get address() {
331
+ return this.account?.address || null;
332
+ }
333
+ /**
334
+ * Get ETH balance on Base
335
+ */
336
+ async getBaseBalance(address) {
337
+ const addr = address || this.address;
338
+ if (!addr) throw new Error("No address provided");
339
+ return this.publicClient.getBalance({ address: addr });
340
+ }
341
+ /**
342
+ * Get USDC balance on Base
343
+ */
344
+ async getBaseUsdcBalance(address) {
345
+ const addr = address || this.address;
346
+ if (!addr) throw new Error("No address provided");
347
+ return this.publicClient.readContract({
348
+ address: BASE_USDC,
349
+ abi: ERC20_ABI,
350
+ functionName: "balanceOf",
351
+ args: [addr]
352
+ });
353
+ }
354
+ /**
355
+ * Bridge ETH from Base to THRYX
356
+ * Sends ETH to the bridge wallet on Base, which triggers automatic minting on THRYX
357
+ *
358
+ * @param amount - Amount of ETH to bridge (e.g., "0.01")
359
+ * @returns Bridge result with transaction hash
360
+ */
361
+ async bridgeETH(amount) {
362
+ if (!this.walletClient || !this.account) {
363
+ return { success: false, error: "Wallet not connected - provide privateKey in constructor" };
364
+ }
365
+ try {
366
+ const amountWei = parseEther(amount);
367
+ const balance = await this.getBaseBalance();
368
+ if (balance < amountWei) {
369
+ return {
370
+ success: false,
371
+ error: `Insufficient balance. Have ${formatEther(balance)} ETH, need ${amount} ETH`
372
+ };
373
+ }
374
+ const txHash = await this.walletClient.sendTransaction({
375
+ to: BRIDGE_WALLET,
376
+ value: amountWei,
377
+ chain: BASE_CHAIN,
378
+ account: this.account
379
+ });
380
+ return {
381
+ success: true,
382
+ txHash,
383
+ amount
384
+ };
385
+ } catch (error) {
386
+ return {
387
+ success: false,
388
+ error: error instanceof Error ? error.message : String(error)
389
+ };
390
+ }
391
+ }
392
+ /**
393
+ * Bridge USDC from Base to THRYX
394
+ * Sends USDC to the bridge wallet on Base, which triggers automatic minting on THRYX
395
+ *
396
+ * @param amount - Amount of USDC to bridge (e.g., "100" for 100 USDC)
397
+ * @returns Bridge result with transaction hash
398
+ */
399
+ async bridgeUSDC(amount) {
400
+ if (!this.walletClient || !this.account) {
401
+ return { success: false, error: "Wallet not connected - provide privateKey in constructor" };
402
+ }
403
+ try {
404
+ const amountUnits = BigInt(Math.floor(parseFloat(amount) * 1e6));
405
+ const balance = await this.getBaseUsdcBalance();
406
+ if (balance < amountUnits) {
407
+ return {
408
+ success: false,
409
+ error: `Insufficient USDC balance. Have ${Number(balance) / 1e6} USDC, need ${amount} USDC`
410
+ };
411
+ }
412
+ const txHash = await this.walletClient.writeContract({
413
+ address: BASE_USDC,
414
+ abi: ERC20_ABI,
415
+ functionName: "transfer",
416
+ args: [BRIDGE_WALLET, amountUnits],
417
+ chain: BASE_CHAIN,
418
+ account: this.account
419
+ });
420
+ return {
421
+ success: true,
422
+ txHash,
423
+ amount
424
+ };
425
+ } catch (error) {
426
+ return {
427
+ success: false,
428
+ error: error instanceof Error ? error.message : String(error)
429
+ };
430
+ }
431
+ }
432
+ /**
433
+ * Get the bridge wallet address
434
+ */
435
+ getBridgeWallet() {
436
+ return BRIDGE_WALLET;
437
+ }
438
+ };
301
439
  var index_default = ThryxSDK;
302
440
  export {
303
441
  AGENT_REGISTRY_ABI,
304
442
  AMM_ABI,
305
443
  BASE_CHAIN,
444
+ BASE_USDC,
445
+ BRIDGE_WALLET,
446
+ BridgeClient,
306
447
  DEFAULT_CONTRACTS,
307
448
  ERC20_ABI,
308
449
  ORACLE_ABI,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thryx/sdk",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "TypeScript SDK for THRYX - AI-Native Blockchain (Chain ID: 77777)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/src/index.ts CHANGED
@@ -170,6 +170,19 @@ export interface PriceData {
170
170
  isStale: boolean;
171
171
  }
172
172
 
173
+ // ==================== Bridge Configuration ====================
174
+
175
+ /**
176
+ * Bridge wallet address on Base mainnet
177
+ * Send ETH to this address on Base to receive ETH on THRYX
178
+ */
179
+ export const BRIDGE_WALLET: Address = '0x338304e35841d2Fa6849EF855f6beBD8988C65B8';
180
+
181
+ /**
182
+ * Base USDC contract address
183
+ */
184
+ export const BASE_USDC: Address = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
185
+
173
186
  // ==================== Default Contract Addresses ====================
174
187
 
175
188
  export const DEFAULT_CONTRACTS: ContractAddresses = {
@@ -415,6 +428,17 @@ export class ThryxSDK {
415
428
  });
416
429
  }
417
430
 
431
+ // ==================== Bridge Operations ====================
432
+
433
+ /**
434
+ * Get a bridge client for Base -> THRYX bridging
435
+ * @param baseRpcUrl - RPC URL for Base mainnet
436
+ * @param privateKey - Private key for signing transactions on Base
437
+ */
438
+ createBridgeClient(baseRpcUrl: string = 'https://mainnet.base.org', privateKey?: string): BridgeClient {
439
+ return new BridgeClient(baseRpcUrl, privateKey);
440
+ }
441
+
418
442
  // ==================== Utilities ====================
419
443
 
420
444
  private hashPair(pair: string): `0x${string}` {
@@ -434,6 +458,181 @@ export class ThryxSDK {
434
458
  }
435
459
  }
436
460
 
461
+ // ==================== Bridge Client ====================
462
+
463
+ export interface BridgeResult {
464
+ success: boolean;
465
+ txHash?: Hash;
466
+ error?: string;
467
+ amount?: string;
468
+ }
469
+
470
+ /**
471
+ * Bridge client for Base -> THRYX transfers
472
+ *
473
+ * @example
474
+ * ```typescript
475
+ * const bridge = new BridgeClient('https://mainnet.base.org', '0xprivatekey');
476
+ *
477
+ * // Bridge 0.01 ETH from Base to THRYX
478
+ * const result = await bridge.bridgeETH('0.01');
479
+ * console.log('Bridge tx:', result.txHash);
480
+ * ```
481
+ */
482
+ export class BridgeClient {
483
+ public readonly publicClient: PublicClient;
484
+ public readonly walletClient: WalletClient | null;
485
+ public readonly account: PrivateKeyAccount | null;
486
+
487
+ constructor(baseRpcUrl: string = 'https://mainnet.base.org', privateKey?: string) {
488
+ // Create public client for Base
489
+ this.publicClient = createPublicClient({
490
+ chain: BASE_CHAIN,
491
+ transport: http(baseRpcUrl),
492
+ });
493
+
494
+ // Create wallet client if private key provided
495
+ if (privateKey) {
496
+ this.account = privateKeyToAccount(privateKey as `0x${string}`);
497
+ this.walletClient = createWalletClient({
498
+ account: this.account,
499
+ chain: BASE_CHAIN,
500
+ transport: http(baseRpcUrl),
501
+ });
502
+ } else {
503
+ this.account = null;
504
+ this.walletClient = null;
505
+ }
506
+ }
507
+
508
+ get address(): Address | null {
509
+ return this.account?.address || null;
510
+ }
511
+
512
+ /**
513
+ * Get ETH balance on Base
514
+ */
515
+ async getBaseBalance(address?: Address): Promise<bigint> {
516
+ const addr = address || this.address;
517
+ if (!addr) throw new Error('No address provided');
518
+ return this.publicClient.getBalance({ address: addr });
519
+ }
520
+
521
+ /**
522
+ * Get USDC balance on Base
523
+ */
524
+ async getBaseUsdcBalance(address?: Address): Promise<bigint> {
525
+ const addr = address || this.address;
526
+ if (!addr) throw new Error('No address provided');
527
+
528
+ return this.publicClient.readContract({
529
+ address: BASE_USDC,
530
+ abi: ERC20_ABI,
531
+ functionName: 'balanceOf',
532
+ args: [addr],
533
+ });
534
+ }
535
+
536
+ /**
537
+ * Bridge ETH from Base to THRYX
538
+ * Sends ETH to the bridge wallet on Base, which triggers automatic minting on THRYX
539
+ *
540
+ * @param amount - Amount of ETH to bridge (e.g., "0.01")
541
+ * @returns Bridge result with transaction hash
542
+ */
543
+ async bridgeETH(amount: string): Promise<BridgeResult> {
544
+ if (!this.walletClient || !this.account) {
545
+ return { success: false, error: 'Wallet not connected - provide privateKey in constructor' };
546
+ }
547
+
548
+ try {
549
+ const amountWei = parseEther(amount);
550
+
551
+ // Check balance
552
+ const balance = await this.getBaseBalance();
553
+ if (balance < amountWei) {
554
+ return {
555
+ success: false,
556
+ error: `Insufficient balance. Have ${formatEther(balance)} ETH, need ${amount} ETH`
557
+ };
558
+ }
559
+
560
+ // Send to bridge wallet
561
+ const txHash = await this.walletClient.sendTransaction({
562
+ to: BRIDGE_WALLET,
563
+ value: amountWei,
564
+ chain: BASE_CHAIN,
565
+ account: this.account,
566
+ });
567
+
568
+ return {
569
+ success: true,
570
+ txHash,
571
+ amount,
572
+ };
573
+ } catch (error) {
574
+ return {
575
+ success: false,
576
+ error: error instanceof Error ? error.message : String(error),
577
+ };
578
+ }
579
+ }
580
+
581
+ /**
582
+ * Bridge USDC from Base to THRYX
583
+ * Sends USDC to the bridge wallet on Base, which triggers automatic minting on THRYX
584
+ *
585
+ * @param amount - Amount of USDC to bridge (e.g., "100" for 100 USDC)
586
+ * @returns Bridge result with transaction hash
587
+ */
588
+ async bridgeUSDC(amount: string): Promise<BridgeResult> {
589
+ if (!this.walletClient || !this.account) {
590
+ return { success: false, error: 'Wallet not connected - provide privateKey in constructor' };
591
+ }
592
+
593
+ try {
594
+ const amountUnits = BigInt(Math.floor(parseFloat(amount) * 1e6)); // USDC has 6 decimals
595
+
596
+ // Check balance
597
+ const balance = await this.getBaseUsdcBalance();
598
+ if (balance < amountUnits) {
599
+ return {
600
+ success: false,
601
+ error: `Insufficient USDC balance. Have ${Number(balance) / 1e6} USDC, need ${amount} USDC`
602
+ };
603
+ }
604
+
605
+ // Transfer USDC to bridge wallet
606
+ const txHash = await this.walletClient.writeContract({
607
+ address: BASE_USDC,
608
+ abi: ERC20_ABI,
609
+ functionName: 'transfer',
610
+ args: [BRIDGE_WALLET, amountUnits],
611
+ chain: BASE_CHAIN,
612
+ account: this.account,
613
+ });
614
+
615
+ return {
616
+ success: true,
617
+ txHash,
618
+ amount,
619
+ };
620
+ } catch (error) {
621
+ return {
622
+ success: false,
623
+ error: error instanceof Error ? error.message : String(error),
624
+ };
625
+ }
626
+ }
627
+
628
+ /**
629
+ * Get the bridge wallet address
630
+ */
631
+ getBridgeWallet(): Address {
632
+ return BRIDGE_WALLET;
633
+ }
634
+ }
635
+
437
636
  // ==================== Exports ====================
438
637
 
439
638
  export default ThryxSDK;