@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.
- package/dist/clients/balances.d.ts +12 -0
- package/dist/clients/balances.d.ts.map +1 -0
- package/dist/clients/balances.js +23 -0
- package/dist/clients/base.d.ts +16 -0
- package/dist/clients/base.d.ts.map +1 -0
- package/dist/clients/base.js +23 -0
- package/dist/clients/relay.d.ts +17 -0
- package/dist/clients/relay.d.ts.map +1 -0
- package/dist/clients/relay.js +66 -0
- package/dist/clients/swaps.d.ts +97 -0
- package/dist/clients/swaps.d.ts.map +1 -0
- package/dist/clients/swaps.js +150 -0
- package/dist/clients/tokens.d.ts +9 -0
- package/dist/clients/tokens.d.ts.map +1 -0
- package/dist/clients/tokens.js +52 -0
- package/dist/clients/transfers.d.ts +36 -0
- package/dist/clients/transfers.d.ts.map +1 -0
- package/dist/clients/transfers.js +43 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +1 -0
- package/dist/config/manager.d.ts +72 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +221 -0
- package/dist/haru-7702.d.ts +85 -0
- package/dist/haru-7702.d.ts.map +1 -0
- package/dist/haru-7702.js +405 -0
- package/dist/haru-v1.d.ts +56 -0
- package/dist/haru-v1.d.ts.map +1 -0
- package/dist/haru-v1.js +71 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/utils/callBuilder.d.ts +4 -0
- package/dist/utils/callBuilder.d.ts.map +1 -0
- package/dist/utils/callBuilder.js +20 -0
- package/package.json +30 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConfigManager - Validate and test configs against the Haru API
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* const result = await ConfigManager.validate(
|
|
7
|
+
* { chains: ['arbitrum'] },
|
|
8
|
+
* { apiKey: 'haru_live_demo123' }
|
|
9
|
+
* );
|
|
10
|
+
*
|
|
11
|
+
* if (result.valid) {
|
|
12
|
+
* console.log('Config is valid!');
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export class ConfigManager {
|
|
17
|
+
static getBaseUrl(options) {
|
|
18
|
+
return options.baseUrl || 'https://api.haruapi.com';
|
|
19
|
+
}
|
|
20
|
+
static getHeaders(options) {
|
|
21
|
+
return {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
'X-API-Key': options.apiKey,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate a config against the API
|
|
28
|
+
* Checks if chains are allowed, tokens can be hydrated, etc.
|
|
29
|
+
*/
|
|
30
|
+
static async validate(config, options) {
|
|
31
|
+
const baseUrl = this.getBaseUrl(options);
|
|
32
|
+
try {
|
|
33
|
+
const response = await fetch(`${baseUrl}/v1/config/verify`, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: this.getHeaders(options),
|
|
36
|
+
body: JSON.stringify({ config }),
|
|
37
|
+
});
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
40
|
+
return {
|
|
41
|
+
valid: false,
|
|
42
|
+
errors: [error.error || `HTTP ${response.status}`],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const result = await response.json();
|
|
46
|
+
return {
|
|
47
|
+
valid: result.verified === true,
|
|
48
|
+
errors: result.error ? [result.error] : [],
|
|
49
|
+
config: result.config,
|
|
50
|
+
hydratedTokens: result.hydratedTokens,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
return {
|
|
55
|
+
valid: false,
|
|
56
|
+
errors: [e.message || 'Network error'],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Test a config by making dry-run calls to all endpoints
|
|
62
|
+
* This validates that the config works for all features
|
|
63
|
+
*/
|
|
64
|
+
static async test(config, options) {
|
|
65
|
+
const baseUrl = this.getBaseUrl(options);
|
|
66
|
+
const headers = {
|
|
67
|
+
'X-API-Key': options.apiKey,
|
|
68
|
+
'X-Haru-Config': JSON.stringify(config),
|
|
69
|
+
};
|
|
70
|
+
const results = {
|
|
71
|
+
tokens: { success: false },
|
|
72
|
+
balances: { success: false },
|
|
73
|
+
swaps: { success: false },
|
|
74
|
+
transfers: { success: false },
|
|
75
|
+
yield: { success: false },
|
|
76
|
+
relay: { success: false },
|
|
77
|
+
};
|
|
78
|
+
// Test tokens
|
|
79
|
+
try {
|
|
80
|
+
const response = await fetch(`${baseUrl}/v1/tokens/defaults`, { headers });
|
|
81
|
+
results.tokens.success = response.ok;
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
const error = await response.json().catch(() => ({}));
|
|
84
|
+
results.tokens.error = error.error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
results.tokens.error = e.message;
|
|
89
|
+
}
|
|
90
|
+
// Test balances (requires userAddress - skip if no chains)
|
|
91
|
+
if (config.chains?.length > 0) {
|
|
92
|
+
try {
|
|
93
|
+
// Use a dummy address for testing
|
|
94
|
+
const dummyAddress = '0x0000000000000000000000000000000000000000';
|
|
95
|
+
const response = await fetch(`${baseUrl}/v1/balances/${dummyAddress}`, { headers });
|
|
96
|
+
// 400 is expected for dummy address, but API should respond
|
|
97
|
+
results.balances.success = response.status === 400 || response.ok;
|
|
98
|
+
if (!response.ok && response.status !== 400) {
|
|
99
|
+
const error = await response.json().catch(() => ({}));
|
|
100
|
+
results.balances.error = error.error;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
results.balances.success = true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
results.balances.error = e.message;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Test swaps
|
|
111
|
+
try {
|
|
112
|
+
const response = await fetch(`${baseUrl}/v1/swaps/quote-by-usd`, {
|
|
113
|
+
method: 'POST',
|
|
114
|
+
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
userAddress: '0x0000000000000000000000000000000000000000',
|
|
117
|
+
fromSymbol: 'USDC',
|
|
118
|
+
toSymbol: 'WETH',
|
|
119
|
+
usdValue: '100',
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
// 400 is expected for dummy data, but API should respond
|
|
123
|
+
results.swaps.success = response.status === 400 || response.ok;
|
|
124
|
+
if (!response.ok && response.status !== 400) {
|
|
125
|
+
const error = await response.json().catch(() => ({}));
|
|
126
|
+
results.swaps.error = error.error;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
results.swaps.success = true;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
results.swaps.error = e.message;
|
|
134
|
+
}
|
|
135
|
+
// Test transfers
|
|
136
|
+
try {
|
|
137
|
+
const response = await fetch(`${baseUrl}/v1/transfers/by-usd`, {
|
|
138
|
+
method: 'POST',
|
|
139
|
+
headers: { ...headers, 'Content-Type': 'application/json' },
|
|
140
|
+
body: JSON.stringify({
|
|
141
|
+
fromUser: '0x0000000000000000000000000000000000000000',
|
|
142
|
+
toUser: '0x0000000000000000000000000000000000000001',
|
|
143
|
+
tokenSymbol: 'USDC',
|
|
144
|
+
usdValue: '100',
|
|
145
|
+
}),
|
|
146
|
+
});
|
|
147
|
+
results.transfers.success = response.status === 400 || response.ok;
|
|
148
|
+
if (!response.ok && response.status !== 400) {
|
|
149
|
+
const error = await response.json().catch(() => ({}));
|
|
150
|
+
results.transfers.error = error.error;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
results.transfers.success = true;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
results.transfers.error = e.message;
|
|
158
|
+
}
|
|
159
|
+
// Test yield
|
|
160
|
+
try {
|
|
161
|
+
const response = await fetch(`${baseUrl}/v1/yield/rates`, { headers });
|
|
162
|
+
results.yield.success = response.ok;
|
|
163
|
+
if (!response.ok) {
|
|
164
|
+
const error = await response.json().catch(() => ({}));
|
|
165
|
+
results.yield.error = error.error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
results.yield.error = e.message;
|
|
170
|
+
}
|
|
171
|
+
// Test relay
|
|
172
|
+
try {
|
|
173
|
+
const response = await fetch(`${baseUrl}/v1/relay/sponsor`, { headers });
|
|
174
|
+
results.relay.success = response.ok;
|
|
175
|
+
if (!response.ok) {
|
|
176
|
+
const error = await response.json().catch(() => ({}));
|
|
177
|
+
results.relay.error = error.error;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
results.relay.error = e.message;
|
|
182
|
+
}
|
|
183
|
+
return results;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Create a config from a template
|
|
187
|
+
* This is local-only, doesn't validate against API
|
|
188
|
+
*/
|
|
189
|
+
static create(template) {
|
|
190
|
+
const now = Date.now();
|
|
191
|
+
const templates = {
|
|
192
|
+
minimal: {
|
|
193
|
+
chains: ['arbitrum'],
|
|
194
|
+
sig: '',
|
|
195
|
+
ts: now,
|
|
196
|
+
exp: now + 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
197
|
+
},
|
|
198
|
+
default: {
|
|
199
|
+
chains: ['arbitrum', 'base'],
|
|
200
|
+
tokens: ['USDC', 'WETH'],
|
|
201
|
+
primaryUsd: ['USDC'],
|
|
202
|
+
sig: '',
|
|
203
|
+
ts: now,
|
|
204
|
+
exp: now + 30 * 24 * 60 * 60 * 1000,
|
|
205
|
+
},
|
|
206
|
+
full: {
|
|
207
|
+
chains: ['arbitrum', 'base', 'optimism', 'ethereum'],
|
|
208
|
+
tokens: ['USDC', 'USDT', 'WETH', 'WBTC'],
|
|
209
|
+
primaryUsd: ['USDC', 'USDT'],
|
|
210
|
+
yield: {
|
|
211
|
+
enabled: true,
|
|
212
|
+
allowList: ['USDC', 'USDT'],
|
|
213
|
+
},
|
|
214
|
+
sig: '',
|
|
215
|
+
ts: now,
|
|
216
|
+
exp: now + 30 * 24 * 60 * 60 * 1000,
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
return templates[template || 'default'];
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { type Address } from 'viem';
|
|
2
|
+
import type { CleanSwapQuote, CleanTransfer, EIP7702Call, ChainCallBundle, SignedBatch, SimulationResult, TxStatus, NonceMetadata, SponsorTxResponse, PrivySignRawHash, Haru7702Options as Haru7702OptionsType, MultiInputSwapQuote } from '@harukit/types';
|
|
3
|
+
export type { Haru7702Options } from '@harukit/types';
|
|
4
|
+
/**
|
|
5
|
+
* Haru7702 — EIP-7702 batch transaction client with gas sponsorship.
|
|
6
|
+
*
|
|
7
|
+
* @example Single-chain swap (one-shot)
|
|
8
|
+
* ```ts
|
|
9
|
+
* const haru = new Haru7702({ apiKey: '...' }); // defaultChain = 'arbitrum'
|
|
10
|
+
* await haru.executeSwap({ quote, wallet, signAuthorization });
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* @example Multi-chain swap (automatic parallel execution)
|
|
14
|
+
* ```ts
|
|
15
|
+
* const haru = new Haru7702({ apiKey: '...' });
|
|
16
|
+
* const batches = haru.buildCalls(quote); // Map { 'arbitrum' → ChainCallBundle, 'base' → ChainCallBundle }
|
|
17
|
+
* await haru.executeSwap({ quote, wallet, signAuthorization }); // handles multi-chain automatically
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @example Transfer
|
|
21
|
+
* ```ts
|
|
22
|
+
* await haru.executeTransfer({ transfer, wallet, signAuthorization });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class Haru7702 {
|
|
26
|
+
private defaultChain;
|
|
27
|
+
private apiBaseUrl;
|
|
28
|
+
private apiKey;
|
|
29
|
+
constructor(options?: Haru7702OptionsType);
|
|
30
|
+
private getHeaders;
|
|
31
|
+
private serializeWithBigInt;
|
|
32
|
+
createSignRawHash(wallet: any): Promise<PrivySignRawHash>;
|
|
33
|
+
signAuthorization(signAuthorization: any, walletAddress: string, chain?: string): Promise<string>;
|
|
34
|
+
signBatchCall(calls: EIP7702Call[], nonce: bigint, deadline: bigint, sponsor: Address, signRawHash: PrivySignRawHash, walletAddress: string, chain?: string): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Build execution calls from a swap quote or transfer.
|
|
37
|
+
* Always returns calls grouped by chain as Map<chain, ChainCallBundle>.
|
|
38
|
+
* Works for both single-chain and multi-chain operations.
|
|
39
|
+
*/
|
|
40
|
+
buildCalls(quote: CleanSwapQuote | MultiInputSwapQuote | CleanTransfer): Map<string, ChainCallBundle>;
|
|
41
|
+
/**
|
|
42
|
+
* Execute a swap in one call. Handles multi-chain automatically.
|
|
43
|
+
* Returns immediately with transaction hashes (does not wait for confirmation).
|
|
44
|
+
*/
|
|
45
|
+
executeSwap(params: {
|
|
46
|
+
quote: CleanSwapQuote | MultiInputSwapQuote;
|
|
47
|
+
wallet: any;
|
|
48
|
+
signAuthorization: any;
|
|
49
|
+
deadline?: bigint;
|
|
50
|
+
}): Promise<Map<string, SponsorTxResponse>>;
|
|
51
|
+
/**
|
|
52
|
+
* Execute a transfer in one call.
|
|
53
|
+
* Returns immediately with transaction hash (does not wait for confirmation).
|
|
54
|
+
*/
|
|
55
|
+
executeTransfer(params: {
|
|
56
|
+
transfer: CleanTransfer;
|
|
57
|
+
wallet: any;
|
|
58
|
+
signAuthorization: any;
|
|
59
|
+
deadline?: bigint;
|
|
60
|
+
}): Promise<Map<string, SponsorTxResponse>>;
|
|
61
|
+
/**
|
|
62
|
+
* Execute a pre-built bundle (from buildCalls) in one call.
|
|
63
|
+
* Useful when you've combined multiple quotes into a single bundle.
|
|
64
|
+
* Returns immediately with transaction hash (does not wait for confirmation).
|
|
65
|
+
*/
|
|
66
|
+
executeBatch(params: {
|
|
67
|
+
bundle: ChainCallBundle;
|
|
68
|
+
wallet: any;
|
|
69
|
+
signAuthorization: any;
|
|
70
|
+
deadline?: bigint;
|
|
71
|
+
}): Promise<Map<string, SponsorTxResponse>>;
|
|
72
|
+
/**
|
|
73
|
+
* Get the contract address for a specific chain.
|
|
74
|
+
* Fetches from the dedicated contract-address endpoint.
|
|
75
|
+
*/
|
|
76
|
+
getContractAddress(chainId: number): Promise<Address>;
|
|
77
|
+
getSponsorAddress(): Promise<Address>;
|
|
78
|
+
getNonce(userAddress: Address, chain?: string): Promise<bigint>;
|
|
79
|
+
getNonceMetadata(userAddress: Address, chainId?: number): Promise<NonceMetadata>;
|
|
80
|
+
simulateTx(authorization: string, signedBatch: SignedBatch, userEOA: Address, chain?: string): Promise<SimulationResult>;
|
|
81
|
+
sponsorTx(signedBatch: SignedBatch, authorization: string, userEOA: Address, chain?: string): Promise<SponsorTxResponse>;
|
|
82
|
+
waitForTx(txHash: string, chain?: string): Promise<TxStatus>;
|
|
83
|
+
getTxStatus(txHash: string, chain?: string): Promise<TxStatus>;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=haru-7702.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"haru-7702.d.ts","sourceRoot":"","sources":["../src/haru-7702.ts"],"names":[],"mappings":"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"}
|