@harukit/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.
@@ -0,0 +1,12 @@
1
+ import { BaseClient } from './base';
2
+ import type { CategorizedBalanceResult, YoloBalanceResult } from '@harukit/types';
3
+ export declare class BalancesClient extends BaseClient {
4
+ get(userAddress: string): Promise<CategorizedBalanceResult>;
5
+ /**
6
+ * Get ALL token balances for a user (yolo mode).
7
+ * Returns every token with balance > 0, including unlisted tokens.
8
+ * Requires config.yoloMode = true.
9
+ */
10
+ getAll(userAddress: string): Promise<YoloBalanceResult>;
11
+ }
12
+ //# sourceMappingURL=balances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balances.d.ts","sourceRoot":"","sources":["../../src/clients/balances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAElF,qBAAa,cAAe,SAAQ,UAAU;IACtC,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAajE;;;;OAIG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAa9D"}
@@ -0,0 +1,23 @@
1
+ import { BaseClient } from './base';
2
+ export class BalancesClient extends BaseClient {
3
+ async get(userAddress) {
4
+ const response = await fetch(`${this.baseUrl}/v1/balances/${userAddress}`, { headers: this.getHeaders() });
5
+ if (!response.ok) {
6
+ throw new Error('Failed to fetch balances');
7
+ }
8
+ return response.json();
9
+ }
10
+ /**
11
+ * Get ALL token balances for a user (yolo mode).
12
+ * Returns every token with balance > 0, including unlisted tokens.
13
+ * Requires config.yoloMode = true.
14
+ */
15
+ async getAll(userAddress) {
16
+ const response = await fetch(`${this.baseUrl}/v1/balances/${userAddress}/all`, { headers: this.getHeaders() });
17
+ if (!response.ok) {
18
+ const error = await response.json().catch(() => ({ error: 'Unknown error' }));
19
+ throw new Error(error.error || 'Failed to fetch all balances');
20
+ }
21
+ return response.json();
22
+ }
23
+ }
@@ -0,0 +1,16 @@
1
+ import type { Config } from '@harukit/types';
2
+ export interface BaseClientOptions {
3
+ apiKey: string;
4
+ baseUrl: string;
5
+ config: Config;
6
+ }
7
+ export declare abstract class BaseClient {
8
+ protected apiKey: string;
9
+ protected baseUrl: string;
10
+ protected config: Config;
11
+ constructor(options: BaseClientOptions);
12
+ protected getHeaders(): HeadersInit;
13
+ getConfig(): Config;
14
+ setConfig(config: Config): void;
15
+ }
16
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/clients/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,8BAAsB,UAAU;IAC9B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,iBAAiB;IAMtC,SAAS,CAAC,UAAU,IAAI,WAAW;IAQnC,SAAS,IAAI,MAAM;IAInB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGhC"}
@@ -0,0 +1,23 @@
1
+ export class BaseClient {
2
+ apiKey;
3
+ baseUrl;
4
+ config;
5
+ constructor(options) {
6
+ this.apiKey = options.apiKey;
7
+ this.baseUrl = options.baseUrl.replace(/\/$/, '');
8
+ this.config = options.config;
9
+ }
10
+ getHeaders() {
11
+ return {
12
+ 'Content-Type': 'application/json',
13
+ 'X-API-Key': this.apiKey,
14
+ 'X-Haru-Config': JSON.stringify(this.config),
15
+ };
16
+ }
17
+ getConfig() {
18
+ return this.config;
19
+ }
20
+ setConfig(config) {
21
+ this.config = config;
22
+ }
23
+ }
@@ -0,0 +1,17 @@
1
+ import { BaseClient } from './base';
2
+ import type { SimulationResult, TxStatus } from '@harukit/types';
3
+ export interface RelayCall {
4
+ to: string;
5
+ data: string;
6
+ value?: string;
7
+ }
8
+ export declare class RelayClient extends BaseClient {
9
+ getNonce(userAddress: string, chain?: string): Promise<bigint>;
10
+ getSponsorAddress(): Promise<string>;
11
+ simulate(calls: RelayCall[]): Promise<SimulationResult>;
12
+ execute(calls: RelayCall[]): Promise<{
13
+ txHash: string;
14
+ }>;
15
+ getStatus(txHash: string, chain?: string): Promise<TxStatus>;
16
+ }
17
+ //# sourceMappingURL=relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/clients/relay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEjE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD,qBAAa,WAAY,SAAQ,UAAU;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAc9D,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAapC,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAcvD,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAcxD,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAYnE"}
@@ -0,0 +1,66 @@
1
+ import { BaseClient } from './base';
2
+ import { CHAIN_NAME_TO_ID } from '@harukit/shared';
3
+ function resolveChainQueryParam(chain) {
4
+ if (!chain)
5
+ return '';
6
+ const id = CHAIN_NAME_TO_ID[chain.toLowerCase()];
7
+ if (id === undefined) {
8
+ throw new Error(`Unsupported chain: "${chain}". Supported: ${Object.keys(CHAIN_NAME_TO_ID).join(', ')}`);
9
+ }
10
+ return `?chainId=${id}`;
11
+ }
12
+ export class RelayClient extends BaseClient {
13
+ async getNonce(userAddress, chain) {
14
+ const query = resolveChainQueryParam(chain);
15
+ const response = await fetch(`${this.baseUrl}/v1/relay/nonce/${userAddress}${query}`, {
16
+ headers: this.getHeaders(),
17
+ });
18
+ if (!response.ok) {
19
+ throw new Error('Failed to get nonce');
20
+ }
21
+ const data = await response.json();
22
+ return BigInt(data.nonce);
23
+ }
24
+ async getSponsorAddress() {
25
+ const response = await fetch(`${this.baseUrl}/v1/relay/sponsor`, {
26
+ headers: this.getHeaders(),
27
+ });
28
+ if (!response.ok) {
29
+ throw new Error('Failed to get sponsor address');
30
+ }
31
+ const data = await response.json();
32
+ return data.sponsorAddress;
33
+ }
34
+ async simulate(calls) {
35
+ const response = await fetch(`${this.baseUrl}/v1/relay/simulate`, {
36
+ method: 'POST',
37
+ headers: this.getHeaders(),
38
+ body: JSON.stringify({ calls }),
39
+ });
40
+ if (!response.ok) {
41
+ throw new Error('Failed to simulate transaction');
42
+ }
43
+ return response.json();
44
+ }
45
+ async execute(calls) {
46
+ const response = await fetch(`${this.baseUrl}/v1/relay/execute`, {
47
+ method: 'POST',
48
+ headers: this.getHeaders(),
49
+ body: JSON.stringify({ calls }),
50
+ });
51
+ if (!response.ok) {
52
+ throw new Error('Failed to execute transaction');
53
+ }
54
+ return response.json();
55
+ }
56
+ async getStatus(txHash, chain) {
57
+ const query = resolveChainQueryParam(chain);
58
+ const response = await fetch(`${this.baseUrl}/v1/relay/transactions/${txHash}/status${query}`, {
59
+ headers: this.getHeaders(),
60
+ });
61
+ if (!response.ok) {
62
+ throw new Error('Failed to get transaction status');
63
+ }
64
+ return response.json();
65
+ }
66
+ }
@@ -0,0 +1,97 @@
1
+ import { BaseClient } from './base';
2
+ import type { CleanSwapQuote, SwapCallList, SwapStepsLegacy, MultiInputSwapQuote } from '@harukit/types';
3
+ export interface SwapByUsdParams {
4
+ userAddress: string;
5
+ fromSymbol: string;
6
+ fromChain: string;
7
+ toSymbol: string;
8
+ toChain: string;
9
+ usdValue: string;
10
+ }
11
+ export interface SwapByAmountParams {
12
+ userAddress: string;
13
+ fromSymbol: string;
14
+ fromChain: string;
15
+ toSymbol: string;
16
+ toChain: string;
17
+ amount: string;
18
+ }
19
+ export interface SwapByAddressParams {
20
+ userAddress: string;
21
+ fromTokenAddress: string;
22
+ fromChain: string;
23
+ toTokenAddress: string;
24
+ toChain: string;
25
+ amount: string;
26
+ }
27
+ export interface MultiInputByUsdParams {
28
+ userAddress: string;
29
+ origins: {
30
+ chain: string;
31
+ currency: string;
32
+ usdValue: string;
33
+ }[];
34
+ destinationChain: string;
35
+ destinationCurrency: string;
36
+ partial?: boolean;
37
+ recipient?: string;
38
+ }
39
+ export interface MultiInputByAmountParams {
40
+ userAddress: string;
41
+ origins: {
42
+ chain: string;
43
+ currency: string;
44
+ amount: string;
45
+ }[];
46
+ destinationChain: string;
47
+ destinationCurrency: string;
48
+ partial?: boolean;
49
+ recipient?: string;
50
+ }
51
+ export interface MultiInputByAddressParams {
52
+ userAddress: string;
53
+ origins: {
54
+ chain: string;
55
+ tokenAddress: string;
56
+ amount: string;
57
+ }[];
58
+ destinationChain: string;
59
+ destinationTokenAddress: string;
60
+ partial?: boolean;
61
+ recipient?: string;
62
+ }
63
+ export interface Call {
64
+ to: string;
65
+ data: string;
66
+ value: bigint;
67
+ }
68
+ export declare class SwapsClient extends BaseClient {
69
+ getQuoteByUsd(params: SwapByUsdParams): Promise<CleanSwapQuote>;
70
+ getQuoteByAmount(params: SwapByAmountParams): Promise<CleanSwapQuote>;
71
+ /**
72
+ * YOLO MODE: Get swap quote using raw token addresses
73
+ * Requires yoloMode: true in config
74
+ */
75
+ getQuoteByAddress(params: SwapByAddressParams): Promise<CleanSwapQuote>;
76
+ /**
77
+ * Multi-Input by USD - Swap from multiple origins by USD value
78
+ */
79
+ getMultiInputByUsd(params: MultiInputByUsdParams): Promise<MultiInputSwapQuote>;
80
+ /**
81
+ * Multi-Input by Amount - Swap from multiple origins by formatted amount
82
+ */
83
+ getMultiInputByAmount(params: MultiInputByAmountParams): Promise<MultiInputSwapQuote>;
84
+ /**
85
+ * Multi-Input by Address (YOLO) - Swap using raw token addresses
86
+ * Requires yoloMode: true in config
87
+ */
88
+ getMultiInputByAddress(params: MultiInputByAddressParams): Promise<MultiInputSwapQuote>;
89
+ /**
90
+ * Build batch calls for EIP-7702 execution
91
+ * Groups all transactions on same chain into single batch
92
+ */
93
+ buildMultiInputBatch(quote: MultiInputSwapQuote): Map<number, Call[]>;
94
+ buildCalls(quote: CleanSwapQuote): SwapCallList | null;
95
+ buildSteps(quote: CleanSwapQuote): SwapStepsLegacy | null;
96
+ }
97
+ //# sourceMappingURL=swaps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swaps.d.ts","sourceRoot":"","sources":["../../src/clients/swaps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ import { BaseClient } from './base';
2
+ import { extractPrivyCalls } from '../utils/callBuilder';
3
+ export class SwapsClient extends BaseClient {
4
+ async getQuoteByUsd(params) {
5
+ const response = await fetch(`${this.baseUrl}/v1/swaps/quote-by-usd`, {
6
+ method: 'POST',
7
+ headers: this.getHeaders(),
8
+ body: JSON.stringify(params),
9
+ });
10
+ if (!response.ok) {
11
+ const errorBody = await response.text();
12
+ throw new Error(`Failed to get swap quote by USD: ${response.status} ${errorBody}`);
13
+ }
14
+ return response.json();
15
+ }
16
+ async getQuoteByAmount(params) {
17
+ const response = await fetch(`${this.baseUrl}/v1/swaps/quote-by-amount`, {
18
+ method: 'POST',
19
+ headers: this.getHeaders(),
20
+ body: JSON.stringify(params),
21
+ });
22
+ if (!response.ok) {
23
+ const errorBody = await response.text();
24
+ throw new Error(`Failed to get swap quote by amount: ${response.status} ${errorBody}`);
25
+ }
26
+ return response.json();
27
+ }
28
+ /**
29
+ * YOLO MODE: Get swap quote using raw token addresses
30
+ * Requires yoloMode: true in config
31
+ */
32
+ async getQuoteByAddress(params) {
33
+ const response = await fetch(`${this.baseUrl}/v1/swaps/quote-by-address`, {
34
+ method: 'POST',
35
+ headers: this.getHeaders(),
36
+ body: JSON.stringify(params),
37
+ });
38
+ if (!response.ok) {
39
+ const errorBody = await response.text();
40
+ throw new Error(`Failed to get swap quote by address: ${response.status} ${errorBody}`);
41
+ }
42
+ return response.json();
43
+ }
44
+ /**
45
+ * Multi-Input by USD - Swap from multiple origins by USD value
46
+ */
47
+ async getMultiInputByUsd(params) {
48
+ const response = await fetch(`${this.baseUrl}/v1/swaps/multi-input-by-usd`, {
49
+ method: 'POST',
50
+ headers: this.getHeaders(),
51
+ body: JSON.stringify(params),
52
+ });
53
+ if (!response.ok) {
54
+ const errorBody = await response.text();
55
+ throw new Error(`Failed to get multi-input by USD: ${response.status} ${errorBody}`);
56
+ }
57
+ return response.json();
58
+ }
59
+ /**
60
+ * Multi-Input by Amount - Swap from multiple origins by formatted amount
61
+ */
62
+ async getMultiInputByAmount(params) {
63
+ const response = await fetch(`${this.baseUrl}/v1/swaps/multi-input-by-amount`, {
64
+ method: 'POST',
65
+ headers: this.getHeaders(),
66
+ body: JSON.stringify(params),
67
+ });
68
+ if (!response.ok) {
69
+ const errorBody = await response.text();
70
+ throw new Error(`Failed to get multi-input by amount: ${response.status} ${errorBody}`);
71
+ }
72
+ return response.json();
73
+ }
74
+ /**
75
+ * Multi-Input by Address (YOLO) - Swap using raw token addresses
76
+ * Requires yoloMode: true in config
77
+ */
78
+ async getMultiInputByAddress(params) {
79
+ const response = await fetch(`${this.baseUrl}/v1/swaps/multi-input-by-address`, {
80
+ method: 'POST',
81
+ headers: this.getHeaders(),
82
+ body: JSON.stringify(params),
83
+ });
84
+ if (!response.ok) {
85
+ const errorBody = await response.text();
86
+ throw new Error(`Failed to get multi-input by address: ${response.status} ${errorBody}`);
87
+ }
88
+ return response.json();
89
+ }
90
+ /**
91
+ * Build batch calls for EIP-7702 execution
92
+ * Groups all transactions on same chain into single batch
93
+ */
94
+ buildMultiInputBatch(quote) {
95
+ const batches = new Map();
96
+ for (const step of quote.steps) {
97
+ if (step.kind !== 'transaction')
98
+ continue;
99
+ for (const item of step.items) {
100
+ const calls = batches.get(step.chainId) || [];
101
+ calls.push({
102
+ to: item.data.to,
103
+ data: item.data.data,
104
+ value: BigInt(item.data.value || '0'),
105
+ });
106
+ batches.set(step.chainId, calls);
107
+ }
108
+ }
109
+ return batches;
110
+ }
111
+ buildCalls(quote) {
112
+ if (!quote.txData?.steps || quote.txData.steps.length === 0) {
113
+ return null;
114
+ }
115
+ const calls = extractPrivyCalls(quote.txData.steps);
116
+ const metadata = {
117
+ totalSteps: quote.txData.steps.length,
118
+ steps: quote.txData.steps.map((step) => ({
119
+ name: step.stage,
120
+ step: step.step,
121
+ description: step.stage === 'approve'
122
+ ? `Approve ${quote.tokens.in.symbol}`
123
+ : `Swap ${quote.tokens.in.symbol} for ${quote.tokens.out.symbol}`,
124
+ })),
125
+ };
126
+ return { calls, metadata };
127
+ }
128
+ buildSteps(quote) {
129
+ if (!quote.txData?.steps || quote.txData.steps.length === 0) {
130
+ return null;
131
+ }
132
+ const steps = quote.txData.steps.map((step) => ({
133
+ name: step.stage,
134
+ step: step.step,
135
+ description: step.stage === 'approve'
136
+ ? `Approve ${quote.tokens.in.symbol}`
137
+ : `Swap ${quote.tokens.in.symbol} for ${quote.tokens.out.symbol}`,
138
+ }));
139
+ const callList = quote.txData.steps.map((step) => ({
140
+ to: step.data.to,
141
+ data: step.data.data,
142
+ value: step.data.value,
143
+ chainId: step.data.chainId,
144
+ gas: step.data.gas,
145
+ maxFeePerGas: step.data.maxFeePerGas,
146
+ maxPriorityFeePerGas: step.data.maxPriorityFeePerGas,
147
+ }));
148
+ return { totalSteps: quote.txData.steps.length, steps, callList };
149
+ }
150
+ }
@@ -0,0 +1,9 @@
1
+ import { BaseClient } from './base';
2
+ import type { Token, TokenSearchOptions } from '@harukit/types';
3
+ export declare class TokensClient extends BaseClient {
4
+ search(query: string, options?: TokenSearchOptions): Promise<Token[]>;
5
+ getByAddress(address: string, chainId: number): Promise<Token[]>;
6
+ getDefaults(): Promise<Token[]>;
7
+ getPrice(address: string, chainId: number): Promise<number>;
8
+ }
9
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/clients/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,qBAAa,YAAa,SAAQ,UAAU;IACpC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IA4BrE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAchE,WAAW,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAa/B,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAalE"}
@@ -0,0 +1,52 @@
1
+ import { BaseClient } from './base';
2
+ export class TokensClient extends BaseClient {
3
+ async search(query, options) {
4
+ const params = new URLSearchParams({ term: query });
5
+ if (options?.chainIds) {
6
+ options.chainIds.forEach(id => params.append('chainIds', id.toString()));
7
+ }
8
+ if (options?.verified !== undefined) {
9
+ params.append('verified', options.verified.toString());
10
+ }
11
+ if (options?.includeAllChains !== undefined) {
12
+ params.append('includeAllChains', options.includeAllChains.toString());
13
+ }
14
+ if (options?.limit) {
15
+ params.append('limit', options.limit.toString());
16
+ }
17
+ const response = await fetch(`${this.baseUrl}/v1/tokens/search?${params.toString()}`, {
18
+ headers: this.getHeaders(),
19
+ });
20
+ if (!response.ok) {
21
+ throw new Error('Failed to search tokens');
22
+ }
23
+ const data = await response.json();
24
+ return data.tokens;
25
+ }
26
+ async getByAddress(address, chainId) {
27
+ const response = await fetch(`${this.baseUrl}/v1/tokens/by-address/${address}?chainId=${chainId}`, { headers: this.getHeaders() });
28
+ if (!response.ok) {
29
+ throw new Error('Failed to get token by address');
30
+ }
31
+ const data = await response.json();
32
+ return data.tokens;
33
+ }
34
+ async getDefaults() {
35
+ const response = await fetch(`${this.baseUrl}/v1/tokens/defaults`, {
36
+ headers: this.getHeaders(),
37
+ });
38
+ if (!response.ok) {
39
+ throw new Error('Failed to get default tokens');
40
+ }
41
+ const data = await response.json();
42
+ return data.tokens;
43
+ }
44
+ async getPrice(address, chainId) {
45
+ const response = await fetch(`${this.baseUrl}/v1/tokens/${address}/price?chainId=${chainId}`, { headers: this.getHeaders() });
46
+ if (!response.ok) {
47
+ throw new Error('Failed to get token price');
48
+ }
49
+ const data = await response.json();
50
+ return data.price;
51
+ }
52
+ }
@@ -0,0 +1,36 @@
1
+ import { BaseClient } from './base';
2
+ import type { CleanTransfer } from '@harukit/types';
3
+ export interface TransferByUsdParams {
4
+ fromUser: string;
5
+ toUser: string;
6
+ tokenSymbol: string;
7
+ fromChain: string;
8
+ toChain: string;
9
+ usdValue: string;
10
+ }
11
+ export interface TransferByAmountParams {
12
+ fromUser: string;
13
+ toUser: string;
14
+ tokenSymbol: string;
15
+ fromChain: string;
16
+ toChain: string;
17
+ amount: string;
18
+ }
19
+ export interface TransferByAddressParams {
20
+ fromUser: string;
21
+ toUser: string;
22
+ tokenAddress: string;
23
+ fromChain: string;
24
+ toChain: string;
25
+ amount: string;
26
+ }
27
+ export declare class TransfersClient extends BaseClient {
28
+ getByUsd(params: TransferByUsdParams): Promise<CleanTransfer>;
29
+ getByAmount(params: TransferByAmountParams): Promise<CleanTransfer>;
30
+ /**
31
+ * YOLO MODE: Get transfer using raw token address
32
+ * Requires yoloMode: true in config
33
+ */
34
+ getByAddress(params: TransferByAddressParams): Promise<CleanTransfer>;
35
+ }
36
+ //# sourceMappingURL=transfers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfers.d.ts","sourceRoot":"","sources":["../../src/clients/transfers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,eAAgB,SAAQ,UAAU;IACvC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC;IAe7D,WAAW,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC;IAezE;;;OAGG;IACG,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC;CAc5E"}
@@ -0,0 +1,43 @@
1
+ import { BaseClient } from './base';
2
+ export class TransfersClient extends BaseClient {
3
+ async getByUsd(params) {
4
+ const response = await fetch(`${this.baseUrl}/v1/transfers/by-usd`, {
5
+ method: 'POST',
6
+ headers: this.getHeaders(),
7
+ body: JSON.stringify(params),
8
+ });
9
+ if (!response.ok) {
10
+ const errorBody = await response.text();
11
+ throw new Error(`Failed to get transfer by USD: ${response.status} ${errorBody}`);
12
+ }
13
+ return response.json();
14
+ }
15
+ async getByAmount(params) {
16
+ const response = await fetch(`${this.baseUrl}/v1/transfers/by-amount`, {
17
+ method: 'POST',
18
+ headers: this.getHeaders(),
19
+ body: JSON.stringify(params),
20
+ });
21
+ if (!response.ok) {
22
+ const errorBody = await response.text();
23
+ throw new Error(`Failed to get transfer by amount: ${response.status} ${errorBody}`);
24
+ }
25
+ return response.json();
26
+ }
27
+ /**
28
+ * YOLO MODE: Get transfer using raw token address
29
+ * Requires yoloMode: true in config
30
+ */
31
+ async getByAddress(params) {
32
+ const response = await fetch(`${this.baseUrl}/v1/transfers/by-address`, {
33
+ method: 'POST',
34
+ headers: this.getHeaders(),
35
+ body: JSON.stringify(params),
36
+ });
37
+ if (!response.ok) {
38
+ const errorBody = await response.text();
39
+ throw new Error(`Failed to get transfer by address: ${response.status} ${errorBody}`);
40
+ }
41
+ return response.json();
42
+ }
43
+ }
@@ -0,0 +1,2 @@
1
+ export { ConfigManager, type ValidationResult, type TestResults, type ConfigManagerOptions } from './manager';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1 @@
1
+ export { ConfigManager } from './manager';
@@ -0,0 +1,72 @@
1
+ import type { Config, HydratedToken } from '@harukit/types';
2
+ export interface ValidationResult {
3
+ valid: boolean;
4
+ errors: string[];
5
+ config?: Partial<Config>;
6
+ hydratedTokens?: HydratedToken[];
7
+ }
8
+ export interface TestResults {
9
+ tokens: {
10
+ success: boolean;
11
+ error?: string;
12
+ };
13
+ balances: {
14
+ success: boolean;
15
+ error?: string;
16
+ };
17
+ swaps: {
18
+ success: boolean;
19
+ error?: string;
20
+ };
21
+ transfers: {
22
+ success: boolean;
23
+ error?: string;
24
+ };
25
+ yield: {
26
+ success: boolean;
27
+ error?: string;
28
+ };
29
+ relay: {
30
+ success: boolean;
31
+ error?: string;
32
+ };
33
+ }
34
+ export interface ConfigManagerOptions {
35
+ apiKey: string;
36
+ baseUrl?: string;
37
+ }
38
+ /**
39
+ * ConfigManager - Validate and test configs against the Haru API
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const result = await ConfigManager.validate(
44
+ * { chains: ['arbitrum'] },
45
+ * { apiKey: 'haru_live_demo123' }
46
+ * );
47
+ *
48
+ * if (result.valid) {
49
+ * console.log('Config is valid!');
50
+ * }
51
+ * ```
52
+ */
53
+ export declare class ConfigManager {
54
+ private static getBaseUrl;
55
+ private static getHeaders;
56
+ /**
57
+ * Validate a config against the API
58
+ * Checks if chains are allowed, tokens can be hydrated, etc.
59
+ */
60
+ static validate(config: Config, options: ConfigManagerOptions): Promise<ValidationResult>;
61
+ /**
62
+ * Test a config by making dry-run calls to all endpoints
63
+ * This validates that the config works for all features
64
+ */
65
+ static test(config: Config, options: ConfigManagerOptions): Promise<TestResults>;
66
+ /**
67
+ * Create a config from a template
68
+ * This is local-only, doesn't validate against API
69
+ */
70
+ static create(template?: 'minimal' | 'default' | 'full'): Config;
71
+ }
72
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE5D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,SAAS,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB,OAAO,CAAC,MAAM,CAAC,UAAU;IAOzB;;;OAGG;WACU,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAkC/F;;;OAGG;WACU,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAyHtF;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM;CAiCjE"}