moneyos 0.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/LICENSE +21 -0
- package/README.md +56 -0
- package/dist/chunk-RDIRDICH.mjs +408 -0
- package/dist/chunk-RDIRDICH.mjs.map +1 -0
- package/dist/cli/index.js +545 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/index.mjs +152 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/index.d.mts +131 -0
- package/dist/index.d.ts +131 -0
- package/dist/index.js +437 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +21 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aryze
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# MoneyOS
|
|
2
|
+
|
|
3
|
+
The operating system for money. Programmable money primitives for developers and AI agents.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install moneyos
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## CLI
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Check balance
|
|
15
|
+
moneyos balance USDC
|
|
16
|
+
moneyos balance ETH --address 0x...
|
|
17
|
+
|
|
18
|
+
# Send tokens
|
|
19
|
+
moneyos send 10 USDC 0x...
|
|
20
|
+
moneyos send 0.1 ETH 0x...
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## SDK
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { MoneyOS } from "moneyos";
|
|
27
|
+
|
|
28
|
+
const moneyos = new MoneyOS({
|
|
29
|
+
chainId: 42161,
|
|
30
|
+
privateKey: process.env.PRIVATE_KEY,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Check balance
|
|
34
|
+
const balance = await moneyos.balance("USDC");
|
|
35
|
+
console.log(balance.amount); // "250.50"
|
|
36
|
+
|
|
37
|
+
// Send tokens
|
|
38
|
+
const tx = await moneyos.send("USDC", "0x...", "10");
|
|
39
|
+
console.log(tx.hash);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Supported Chains
|
|
43
|
+
|
|
44
|
+
| Chain | ID |
|
|
45
|
+
|-------|-----|
|
|
46
|
+
| Arbitrum | 42161 |
|
|
47
|
+
| Ethereum | 1 |
|
|
48
|
+
| Polygon | 137 |
|
|
49
|
+
|
|
50
|
+
## Supported Tokens
|
|
51
|
+
|
|
52
|
+
USDC, USDT, RYZE, ETH (native)
|
|
53
|
+
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
MIT
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
// src/core/chains.ts
|
|
2
|
+
var chains = {
|
|
3
|
+
arbitrum: {
|
|
4
|
+
id: 42161,
|
|
5
|
+
name: "Arbitrum One",
|
|
6
|
+
rpcUrl: "https://arb1.arbitrum.io/rpc",
|
|
7
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
8
|
+
blockExplorer: "https://arbiscan.io"
|
|
9
|
+
},
|
|
10
|
+
ethereum: {
|
|
11
|
+
id: 1,
|
|
12
|
+
name: "Ethereum",
|
|
13
|
+
rpcUrl: "https://eth.public-rpc.com",
|
|
14
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
15
|
+
blockExplorer: "https://etherscan.io"
|
|
16
|
+
},
|
|
17
|
+
polygon: {
|
|
18
|
+
id: 137,
|
|
19
|
+
name: "Polygon",
|
|
20
|
+
rpcUrl: "https://polygon-rpc.com",
|
|
21
|
+
nativeCurrency: { name: "POL", symbol: "POL", decimals: 18 },
|
|
22
|
+
blockExplorer: "https://polygonscan.com"
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var defaultChain = chains.arbitrum;
|
|
26
|
+
function getChain(idOrName) {
|
|
27
|
+
if (typeof idOrName === "number") {
|
|
28
|
+
return Object.values(chains).find((c) => c.id === idOrName);
|
|
29
|
+
}
|
|
30
|
+
return chains[idOrName.toLowerCase()];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/core/tokens.ts
|
|
34
|
+
var tokens = {
|
|
35
|
+
USDC: {
|
|
36
|
+
symbol: "USDC",
|
|
37
|
+
name: "USD Coin",
|
|
38
|
+
decimals: 6,
|
|
39
|
+
addresses: {
|
|
40
|
+
42161: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
41
|
+
1: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
42
|
+
137: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
USDT: {
|
|
46
|
+
symbol: "USDT",
|
|
47
|
+
name: "Tether USD",
|
|
48
|
+
decimals: 6,
|
|
49
|
+
addresses: {
|
|
50
|
+
42161: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
|
|
51
|
+
1: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
52
|
+
137: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
RYZE: {
|
|
56
|
+
symbol: "RYZE",
|
|
57
|
+
name: "RYZE",
|
|
58
|
+
decimals: 18,
|
|
59
|
+
addresses: {
|
|
60
|
+
42161: "0x7712da72127d5dD213B621497D6E4899d5989e5C"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
function getToken(symbol) {
|
|
65
|
+
return tokens[symbol.toUpperCase()];
|
|
66
|
+
}
|
|
67
|
+
function getTokenAddress(symbol, chainId) {
|
|
68
|
+
return getToken(symbol)?.addresses[chainId];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/core/client.ts
|
|
72
|
+
import {
|
|
73
|
+
createPublicClient,
|
|
74
|
+
createWalletClient,
|
|
75
|
+
http,
|
|
76
|
+
formatUnits,
|
|
77
|
+
parseUnits
|
|
78
|
+
} from "viem";
|
|
79
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
80
|
+
import { arbitrum, mainnet, polygon } from "viem/chains";
|
|
81
|
+
var ERC20_ABI = [
|
|
82
|
+
{
|
|
83
|
+
name: "balanceOf",
|
|
84
|
+
type: "function",
|
|
85
|
+
stateMutability: "view",
|
|
86
|
+
inputs: [{ name: "account", type: "address" }],
|
|
87
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "transfer",
|
|
91
|
+
type: "function",
|
|
92
|
+
stateMutability: "nonpayable",
|
|
93
|
+
inputs: [
|
|
94
|
+
{ name: "to", type: "address" },
|
|
95
|
+
{ name: "amount", type: "uint256" }
|
|
96
|
+
],
|
|
97
|
+
outputs: [{ name: "", type: "bool" }]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "decimals",
|
|
101
|
+
type: "function",
|
|
102
|
+
stateMutability: "view",
|
|
103
|
+
inputs: [],
|
|
104
|
+
outputs: [{ name: "", type: "uint8" }]
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: "symbol",
|
|
108
|
+
type: "function",
|
|
109
|
+
stateMutability: "view",
|
|
110
|
+
inputs: [],
|
|
111
|
+
outputs: [{ name: "", type: "string" }]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "approve",
|
|
115
|
+
type: "function",
|
|
116
|
+
stateMutability: "nonpayable",
|
|
117
|
+
inputs: [
|
|
118
|
+
{ name: "spender", type: "address" },
|
|
119
|
+
{ name: "amount", type: "uint256" }
|
|
120
|
+
],
|
|
121
|
+
outputs: [{ name: "", type: "bool" }]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "allowance",
|
|
125
|
+
type: "function",
|
|
126
|
+
stateMutability: "view",
|
|
127
|
+
inputs: [
|
|
128
|
+
{ name: "owner", type: "address" },
|
|
129
|
+
{ name: "spender", type: "address" }
|
|
130
|
+
],
|
|
131
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
132
|
+
}
|
|
133
|
+
];
|
|
134
|
+
var viemChains = {
|
|
135
|
+
42161: arbitrum,
|
|
136
|
+
1: mainnet,
|
|
137
|
+
137: polygon
|
|
138
|
+
};
|
|
139
|
+
var MoneyOS = class {
|
|
140
|
+
config;
|
|
141
|
+
publicClients = /* @__PURE__ */ new Map();
|
|
142
|
+
walletClient;
|
|
143
|
+
constructor(config) {
|
|
144
|
+
this.config = {
|
|
145
|
+
...config,
|
|
146
|
+
chainId: config.chainId ?? defaultChain.id
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
getPublicClient(chainId) {
|
|
150
|
+
const id = chainId ?? this.config.chainId;
|
|
151
|
+
let client = this.publicClients.get(id);
|
|
152
|
+
if (!client) {
|
|
153
|
+
const chain = viemChains[id];
|
|
154
|
+
const chainInfo = getChain(id);
|
|
155
|
+
const rpcUrl = id === this.config.chainId ? this.config.rpcUrl : void 0;
|
|
156
|
+
client = createPublicClient({
|
|
157
|
+
chain,
|
|
158
|
+
transport: http(rpcUrl ?? chainInfo?.rpcUrl)
|
|
159
|
+
});
|
|
160
|
+
this.publicClients.set(id, client);
|
|
161
|
+
}
|
|
162
|
+
return client;
|
|
163
|
+
}
|
|
164
|
+
getWalletClient() {
|
|
165
|
+
if (!this.walletClient) {
|
|
166
|
+
if (!this.config.privateKey) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
"No private key configured. Set privateKey in MoneyOS config."
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
const account = privateKeyToAccount(this.config.privateKey);
|
|
172
|
+
const chain = viemChains[this.config.chainId];
|
|
173
|
+
const chainInfo = getChain(this.config.chainId);
|
|
174
|
+
this.walletClient = createWalletClient({
|
|
175
|
+
account,
|
|
176
|
+
chain,
|
|
177
|
+
transport: http(this.config.rpcUrl ?? chainInfo?.rpcUrl)
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return this.walletClient;
|
|
181
|
+
}
|
|
182
|
+
get address() {
|
|
183
|
+
if (!this.config.privateKey) {
|
|
184
|
+
throw new Error("No private key configured.");
|
|
185
|
+
}
|
|
186
|
+
return privateKeyToAccount(this.config.privateKey).address;
|
|
187
|
+
}
|
|
188
|
+
async balance(token, options) {
|
|
189
|
+
const chainId = options?.chainId ?? this.config.chainId;
|
|
190
|
+
const account = options?.address ?? this.address;
|
|
191
|
+
const client = this.getPublicClient(chainId);
|
|
192
|
+
if (token.toUpperCase() === "ETH") {
|
|
193
|
+
const raw2 = await client.getBalance({ address: account });
|
|
194
|
+
return {
|
|
195
|
+
token: "ETH",
|
|
196
|
+
symbol: "ETH",
|
|
197
|
+
amount: formatUnits(raw2, 18),
|
|
198
|
+
rawAmount: raw2,
|
|
199
|
+
decimals: 18,
|
|
200
|
+
chainId
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const tokenAddress = getTokenAddress(token, chainId);
|
|
204
|
+
if (!tokenAddress) {
|
|
205
|
+
throw new Error(`Token ${token} not found on chain ${chainId}`);
|
|
206
|
+
}
|
|
207
|
+
const tokenInfo = getToken(token);
|
|
208
|
+
const raw = await client.readContract({
|
|
209
|
+
address: tokenAddress,
|
|
210
|
+
abi: ERC20_ABI,
|
|
211
|
+
functionName: "balanceOf",
|
|
212
|
+
args: [account]
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
token: tokenInfo.name,
|
|
216
|
+
symbol: tokenInfo.symbol,
|
|
217
|
+
amount: formatUnits(raw, tokenInfo.decimals),
|
|
218
|
+
rawAmount: raw,
|
|
219
|
+
decimals: tokenInfo.decimals,
|
|
220
|
+
chainId
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
async send(token, to, amount, options) {
|
|
224
|
+
const chainId = options?.chainId ?? this.config.chainId;
|
|
225
|
+
const walletClient = this.getWalletClient();
|
|
226
|
+
const from = this.address;
|
|
227
|
+
if (token.toUpperCase() === "ETH") {
|
|
228
|
+
const value2 = parseUnits(amount, 18);
|
|
229
|
+
const account = privateKeyToAccount(this.config.privateKey);
|
|
230
|
+
const hash2 = await walletClient.sendTransaction({
|
|
231
|
+
account,
|
|
232
|
+
to,
|
|
233
|
+
value: value2,
|
|
234
|
+
chain: viemChains[chainId]
|
|
235
|
+
});
|
|
236
|
+
return { hash: hash2, from, to, amount, token: "ETH", chainId };
|
|
237
|
+
}
|
|
238
|
+
const tokenAddress = getTokenAddress(token, chainId);
|
|
239
|
+
if (!tokenAddress) {
|
|
240
|
+
throw new Error(`Token ${token} not found on chain ${chainId}`);
|
|
241
|
+
}
|
|
242
|
+
const tokenInfo = getToken(token);
|
|
243
|
+
const value = parseUnits(amount, tokenInfo.decimals);
|
|
244
|
+
const client = this.getPublicClient(chainId);
|
|
245
|
+
const { request } = await client.simulateContract({
|
|
246
|
+
address: tokenAddress,
|
|
247
|
+
abi: ERC20_ABI,
|
|
248
|
+
functionName: "transfer",
|
|
249
|
+
args: [to, value],
|
|
250
|
+
account: privateKeyToAccount(this.config.privateKey)
|
|
251
|
+
});
|
|
252
|
+
const hash = await walletClient.writeContract(request);
|
|
253
|
+
return { hash, from, to, amount, token: tokenInfo.symbol, chainId };
|
|
254
|
+
}
|
|
255
|
+
async swap(tokenIn, tokenOut, amount, provider, options) {
|
|
256
|
+
const chainId = options?.chainId ?? this.config.chainId;
|
|
257
|
+
const walletClient = this.getWalletClient();
|
|
258
|
+
const client = this.getPublicClient(chainId);
|
|
259
|
+
const sender = this.address;
|
|
260
|
+
const tokenInAddress = getTokenAddress(tokenIn, chainId);
|
|
261
|
+
const tokenOutAddress = getTokenAddress(tokenOut, chainId);
|
|
262
|
+
if (!tokenInAddress) {
|
|
263
|
+
throw new Error(`Token ${tokenIn} not found on chain ${chainId}`);
|
|
264
|
+
}
|
|
265
|
+
if (!tokenOutAddress) {
|
|
266
|
+
throw new Error(`Token ${tokenOut} not found on chain ${chainId}`);
|
|
267
|
+
}
|
|
268
|
+
const tokenInInfo = getToken(tokenIn);
|
|
269
|
+
const amountWei = parseUnits(amount, tokenInInfo.decimals);
|
|
270
|
+
const quote = await provider.getQuote({
|
|
271
|
+
chainId,
|
|
272
|
+
tokenIn: tokenInAddress,
|
|
273
|
+
tokenOut: tokenOutAddress,
|
|
274
|
+
amount: amountWei,
|
|
275
|
+
sender,
|
|
276
|
+
slippage: options?.slippage
|
|
277
|
+
});
|
|
278
|
+
const calldata = await provider.getCalldata(quote);
|
|
279
|
+
const currentAllowance = await client.readContract({
|
|
280
|
+
address: tokenInAddress,
|
|
281
|
+
abi: ERC20_ABI,
|
|
282
|
+
functionName: "allowance",
|
|
283
|
+
args: [sender, calldata.to]
|
|
284
|
+
});
|
|
285
|
+
if (currentAllowance < amountWei) {
|
|
286
|
+
const account2 = privateKeyToAccount(this.config.privateKey);
|
|
287
|
+
const { request: approveRequest } = await client.simulateContract({
|
|
288
|
+
address: tokenInAddress,
|
|
289
|
+
abi: ERC20_ABI,
|
|
290
|
+
functionName: "approve",
|
|
291
|
+
args: [calldata.to, amountWei],
|
|
292
|
+
account: account2
|
|
293
|
+
});
|
|
294
|
+
await walletClient.writeContract(approveRequest);
|
|
295
|
+
}
|
|
296
|
+
const account = privateKeyToAccount(this.config.privateKey);
|
|
297
|
+
const hash = await walletClient.sendTransaction({
|
|
298
|
+
account,
|
|
299
|
+
to: calldata.to,
|
|
300
|
+
data: calldata.data,
|
|
301
|
+
value: calldata.value,
|
|
302
|
+
chain: viemChains[chainId]
|
|
303
|
+
});
|
|
304
|
+
const tokenOutInfo = getToken(tokenOut);
|
|
305
|
+
return {
|
|
306
|
+
hash,
|
|
307
|
+
tokenIn: tokenInInfo.symbol,
|
|
308
|
+
tokenOut: tokenOutInfo.symbol,
|
|
309
|
+
amountIn: amount,
|
|
310
|
+
amountOut: formatUnits(BigInt(quote.expectedOut), tokenOutInfo.decimals),
|
|
311
|
+
chainId
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// src/providers/odos.ts
|
|
317
|
+
var ODOS_API = "https://api.odos.xyz";
|
|
318
|
+
var OdosProvider = class {
|
|
319
|
+
name = "odos";
|
|
320
|
+
apiKey;
|
|
321
|
+
constructor(options) {
|
|
322
|
+
this.apiKey = options?.apiKey;
|
|
323
|
+
}
|
|
324
|
+
async getQuote(params) {
|
|
325
|
+
const headers = {
|
|
326
|
+
"Content-Type": "application/json"
|
|
327
|
+
};
|
|
328
|
+
if (this.apiKey) {
|
|
329
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
330
|
+
}
|
|
331
|
+
const response = await fetch(`${ODOS_API}/sor/quote/v2`, {
|
|
332
|
+
method: "POST",
|
|
333
|
+
headers,
|
|
334
|
+
body: JSON.stringify({
|
|
335
|
+
chainId: params.chainId,
|
|
336
|
+
inputTokens: [
|
|
337
|
+
{
|
|
338
|
+
tokenAddress: params.tokenIn,
|
|
339
|
+
amount: params.amount.toString()
|
|
340
|
+
}
|
|
341
|
+
],
|
|
342
|
+
outputTokens: [
|
|
343
|
+
{
|
|
344
|
+
tokenAddress: params.tokenOut,
|
|
345
|
+
proportion: 1
|
|
346
|
+
}
|
|
347
|
+
],
|
|
348
|
+
userAddr: params.sender,
|
|
349
|
+
slippageLimitPercent: params.slippage ?? 1,
|
|
350
|
+
referralCode: 0,
|
|
351
|
+
compact: true
|
|
352
|
+
})
|
|
353
|
+
});
|
|
354
|
+
if (!response.ok) {
|
|
355
|
+
const text = await response.text();
|
|
356
|
+
throw new Error(`Odos quote failed: ${response.status} ${text}`);
|
|
357
|
+
}
|
|
358
|
+
const data = await response.json();
|
|
359
|
+
return {
|
|
360
|
+
tokenIn: params.tokenIn,
|
|
361
|
+
tokenOut: params.tokenOut,
|
|
362
|
+
amountIn: params.amount.toString(),
|
|
363
|
+
expectedOut: data.outAmounts[0],
|
|
364
|
+
router: "",
|
|
365
|
+
chainId: params.chainId,
|
|
366
|
+
pathId: data.pathId
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
async getCalldata(quote) {
|
|
370
|
+
const headers = {
|
|
371
|
+
"Content-Type": "application/json"
|
|
372
|
+
};
|
|
373
|
+
if (this.apiKey) {
|
|
374
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
375
|
+
}
|
|
376
|
+
const response = await fetch(`${ODOS_API}/sor/assemble`, {
|
|
377
|
+
method: "POST",
|
|
378
|
+
headers,
|
|
379
|
+
body: JSON.stringify({
|
|
380
|
+
userAddr: quote.tokenIn,
|
|
381
|
+
pathId: quote.pathId,
|
|
382
|
+
simulate: false
|
|
383
|
+
})
|
|
384
|
+
});
|
|
385
|
+
if (!response.ok) {
|
|
386
|
+
const text = await response.text();
|
|
387
|
+
throw new Error(`Odos assemble failed: ${response.status} ${text}`);
|
|
388
|
+
}
|
|
389
|
+
const data = await response.json();
|
|
390
|
+
return {
|
|
391
|
+
to: data.transaction.to,
|
|
392
|
+
data: data.transaction.data,
|
|
393
|
+
value: BigInt(data.transaction.value)
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
export {
|
|
399
|
+
chains,
|
|
400
|
+
defaultChain,
|
|
401
|
+
getChain,
|
|
402
|
+
tokens,
|
|
403
|
+
getToken,
|
|
404
|
+
getTokenAddress,
|
|
405
|
+
MoneyOS,
|
|
406
|
+
OdosProvider
|
|
407
|
+
};
|
|
408
|
+
//# sourceMappingURL=chunk-RDIRDICH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/chains.ts","../src/core/tokens.ts","../src/core/client.ts","../src/providers/odos.ts"],"sourcesContent":["import type { Chain } from \"./types.js\";\n\nexport const chains: Record<string, Chain> = {\n arbitrum: {\n id: 42161,\n name: \"Arbitrum One\",\n rpcUrl: \"https://arb1.arbitrum.io/rpc\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorer: \"https://arbiscan.io\",\n },\n ethereum: {\n id: 1,\n name: \"Ethereum\",\n rpcUrl: \"https://eth.public-rpc.com\",\n nativeCurrency: { name: \"Ether\", symbol: \"ETH\", decimals: 18 },\n blockExplorer: \"https://etherscan.io\",\n },\n polygon: {\n id: 137,\n name: \"Polygon\",\n rpcUrl: \"https://polygon-rpc.com\",\n nativeCurrency: { name: \"POL\", symbol: \"POL\", decimals: 18 },\n blockExplorer: \"https://polygonscan.com\",\n },\n};\n\nexport const defaultChain = chains.arbitrum;\n\nexport function getChain(idOrName: number | string): Chain | undefined {\n if (typeof idOrName === \"number\") {\n return Object.values(chains).find((c) => c.id === idOrName);\n }\n return chains[idOrName.toLowerCase()];\n}\n","import type { Address } from \"viem\";\n\nexport interface Token {\n symbol: string;\n name: string;\n decimals: number;\n addresses: Record<number, Address>;\n}\n\nexport const tokens: Record<string, Token> = {\n USDC: {\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n addresses: {\n 42161: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\",\n 1: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n 137: \"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359\",\n },\n },\n USDT: {\n symbol: \"USDT\",\n name: \"Tether USD\",\n decimals: 6,\n addresses: {\n 42161: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\",\n 1: \"0xdAC17F958D2ee523a2206206994597C13D831ec7\",\n 137: \"0xc2132D05D31c914a87C6611C10748AEb04B58e8F\",\n },\n },\n RYZE: {\n symbol: \"RYZE\",\n name: \"RYZE\",\n decimals: 18,\n addresses: {\n 42161: \"0x7712da72127d5dD213B621497D6E4899d5989e5C\",\n },\n },\n};\n\nexport function getToken(symbol: string): Token | undefined {\n return tokens[symbol.toUpperCase()];\n}\n\nexport function getTokenAddress(\n symbol: string,\n chainId: number,\n): Address | undefined {\n return getToken(symbol)?.addresses[chainId];\n}\n","import {\n createPublicClient,\n createWalletClient,\n http,\n formatUnits,\n parseUnits,\n type Address,\n type Chain as ViemChain,\n type Hex,\n type PublicClient,\n type WalletClient,\n} from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { arbitrum, mainnet, polygon } from \"viem/chains\";\nimport type {\n MoneyOSConfig,\n Balance,\n SendResult,\n SwapProvider,\n SwapResult,\n} from \"./types.js\";\nimport { getChain, defaultChain } from \"./chains.js\";\nimport { getToken, getTokenAddress } from \"./tokens.js\";\n\nconst ERC20_ABI = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"decimals\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\" }],\n },\n {\n name: \"symbol\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [],\n outputs: [{ name: \"\", type: \"string\" }],\n },\n {\n name: \"approve\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n {\n name: \"allowance\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n] as const;\n\nconst viemChains: Record<number, ViemChain> = {\n 42161: arbitrum,\n 1: mainnet,\n 137: polygon,\n};\n\nexport class MoneyOS {\n private config: MoneyOSConfig;\n private publicClients: Map<number, PublicClient> = new Map();\n private walletClient: WalletClient | undefined;\n\n constructor(config: MoneyOSConfig) {\n this.config = {\n ...config,\n chainId: config.chainId ?? defaultChain.id,\n };\n }\n\n private getPublicClient(chainId?: number): PublicClient {\n const id = chainId ?? this.config.chainId;\n let client = this.publicClients.get(id);\n if (!client) {\n const chain = viemChains[id];\n const chainInfo = getChain(id);\n const rpcUrl =\n id === this.config.chainId ? this.config.rpcUrl : undefined;\n\n client = createPublicClient({\n chain,\n transport: http(rpcUrl ?? chainInfo?.rpcUrl),\n });\n this.publicClients.set(id, client);\n }\n return client;\n }\n\n private getWalletClient(): WalletClient {\n if (!this.walletClient) {\n if (!this.config.privateKey) {\n throw new Error(\n \"No private key configured. Set privateKey in MoneyOS config.\",\n );\n }\n const account = privateKeyToAccount(this.config.privateKey);\n const chain = viemChains[this.config.chainId];\n const chainInfo = getChain(this.config.chainId);\n this.walletClient = createWalletClient({\n account,\n chain,\n transport: http(this.config.rpcUrl ?? chainInfo?.rpcUrl),\n });\n }\n return this.walletClient;\n }\n\n get address(): Address {\n if (!this.config.privateKey) {\n throw new Error(\"No private key configured.\");\n }\n return privateKeyToAccount(this.config.privateKey).address;\n }\n\n async balance(\n token: string,\n options?: { address?: Address; chainId?: number },\n ): Promise<Balance> {\n const chainId = options?.chainId ?? this.config.chainId;\n const account = options?.address ?? this.address;\n const client = this.getPublicClient(chainId);\n\n if (token.toUpperCase() === \"ETH\") {\n const raw = await client.getBalance({ address: account });\n return {\n token: \"ETH\",\n symbol: \"ETH\",\n amount: formatUnits(raw, 18),\n rawAmount: raw,\n decimals: 18,\n chainId,\n };\n }\n\n const tokenAddress = getTokenAddress(token, chainId);\n if (!tokenAddress) {\n throw new Error(`Token ${token} not found on chain ${chainId}`);\n }\n\n const tokenInfo = getToken(token)!;\n const raw = await client.readContract({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [account],\n });\n\n return {\n token: tokenInfo.name,\n symbol: tokenInfo.symbol,\n amount: formatUnits(raw, tokenInfo.decimals),\n rawAmount: raw,\n decimals: tokenInfo.decimals,\n chainId,\n };\n }\n\n async send(\n token: string,\n to: Address,\n amount: string,\n options?: { chainId?: number },\n ): Promise<SendResult> {\n const chainId = options?.chainId ?? this.config.chainId;\n const walletClient = this.getWalletClient();\n const from = this.address;\n\n if (token.toUpperCase() === \"ETH\") {\n const value = parseUnits(amount, 18);\n const account = privateKeyToAccount(this.config.privateKey!);\n const hash = await walletClient.sendTransaction({\n account,\n to,\n value,\n chain: viemChains[chainId],\n });\n return { hash, from, to, amount, token: \"ETH\", chainId };\n }\n\n const tokenAddress = getTokenAddress(token, chainId);\n if (!tokenAddress) {\n throw new Error(`Token ${token} not found on chain ${chainId}`);\n }\n\n const tokenInfo = getToken(token)!;\n const value = parseUnits(amount, tokenInfo.decimals);\n const client = this.getPublicClient(chainId);\n\n const { request } = await client.simulateContract({\n address: tokenAddress,\n abi: ERC20_ABI,\n functionName: \"transfer\",\n args: [to, value],\n account: privateKeyToAccount(this.config.privateKey!),\n });\n\n const hash = await walletClient.writeContract(request);\n return { hash, from, to, amount, token: tokenInfo.symbol, chainId };\n }\n\n async swap(\n tokenIn: string,\n tokenOut: string,\n amount: string,\n provider: SwapProvider,\n options?: { chainId?: number; slippage?: number },\n ): Promise<SwapResult> {\n const chainId = options?.chainId ?? this.config.chainId;\n const walletClient = this.getWalletClient();\n const client = this.getPublicClient(chainId);\n const sender = this.address;\n\n const tokenInAddress = getTokenAddress(tokenIn, chainId);\n const tokenOutAddress = getTokenAddress(tokenOut, chainId);\n if (!tokenInAddress) {\n throw new Error(`Token ${tokenIn} not found on chain ${chainId}`);\n }\n if (!tokenOutAddress) {\n throw new Error(`Token ${tokenOut} not found on chain ${chainId}`);\n }\n\n const tokenInInfo = getToken(tokenIn)!;\n const amountWei = parseUnits(amount, tokenInInfo.decimals);\n\n const quote = await provider.getQuote({\n chainId,\n tokenIn: tokenInAddress,\n tokenOut: tokenOutAddress,\n amount: amountWei,\n sender,\n slippage: options?.slippage,\n });\n\n const calldata = await provider.getCalldata(quote);\n\n const currentAllowance = await client.readContract({\n address: tokenInAddress,\n abi: ERC20_ABI,\n functionName: \"allowance\",\n args: [sender, calldata.to],\n });\n\n if (currentAllowance < amountWei) {\n const account = privateKeyToAccount(this.config.privateKey!);\n const { request: approveRequest } = await client.simulateContract({\n address: tokenInAddress,\n abi: ERC20_ABI,\n functionName: \"approve\",\n args: [calldata.to, amountWei],\n account,\n });\n await walletClient.writeContract(approveRequest);\n }\n\n const account = privateKeyToAccount(this.config.privateKey!);\n const hash = await walletClient.sendTransaction({\n account,\n to: calldata.to,\n data: calldata.data,\n value: calldata.value,\n chain: viemChains[chainId],\n });\n\n const tokenOutInfo = getToken(tokenOut)!;\n return {\n hash,\n tokenIn: tokenInInfo.symbol,\n tokenOut: tokenOutInfo.symbol,\n amountIn: amount,\n amountOut: formatUnits(BigInt(quote.expectedOut), tokenOutInfo.decimals),\n chainId,\n };\n }\n}\n","import type { Address, Hex } from \"viem\";\nimport type { SwapProvider, SwapQuote } from \"../core/types.js\";\n\nconst ODOS_API = \"https://api.odos.xyz\";\n\ninterface OdosQuoteResponse {\n pathId: string;\n outAmounts: string[];\n outValues: number[];\n}\n\ninterface OdosAssembleResponse {\n transaction: {\n to: string;\n data: string;\n value: string;\n };\n}\n\nexport class OdosProvider implements SwapProvider {\n name = \"odos\";\n private apiKey?: string;\n\n constructor(options?: { apiKey?: string }) {\n this.apiKey = options?.apiKey;\n }\n\n async getQuote(params: {\n chainId: number;\n tokenIn: Address;\n tokenOut: Address;\n amount: bigint;\n sender: Address;\n slippage?: number;\n }): Promise<SwapQuote & { pathId: string }> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n const response = await fetch(`${ODOS_API}/sor/quote/v2`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n chainId: params.chainId,\n inputTokens: [\n {\n tokenAddress: params.tokenIn,\n amount: params.amount.toString(),\n },\n ],\n outputTokens: [\n {\n tokenAddress: params.tokenOut,\n proportion: 1,\n },\n ],\n userAddr: params.sender,\n slippageLimitPercent: params.slippage ?? 1,\n referralCode: 0,\n compact: true,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Odos quote failed: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as OdosQuoteResponse;\n\n return {\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amount.toString(),\n expectedOut: data.outAmounts[0],\n router: \"\" as Address,\n chainId: params.chainId,\n pathId: data.pathId,\n };\n }\n\n async getCalldata(\n quote: SwapQuote & { pathId: string },\n ): Promise<{ to: Address; data: Hex; value: bigint }> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n const response = await fetch(`${ODOS_API}/sor/assemble`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n userAddr: quote.tokenIn,\n pathId: quote.pathId,\n simulate: false,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Odos assemble failed: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as OdosAssembleResponse;\n\n return {\n to: data.transaction.to as Address,\n data: data.transaction.data as Hex,\n value: BigInt(data.transaction.value),\n };\n }\n}\n"],"mappings":";AAEO,IAAM,SAAgC;AAAA,EAC3C,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgB,EAAE,MAAM,SAAS,QAAQ,OAAO,UAAU,GAAG;AAAA,IAC7D,eAAe;AAAA,EACjB;AAAA,EACA,UAAU;AAAA,IACR,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgB,EAAE,MAAM,SAAS,QAAQ,OAAO,UAAU,GAAG;AAAA,IAC7D,eAAe;AAAA,EACjB;AAAA,EACA,SAAS;AAAA,IACP,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,gBAAgB,EAAE,MAAM,OAAO,QAAQ,OAAO,UAAU,GAAG;AAAA,IAC3D,eAAe;AAAA,EACjB;AACF;AAEO,IAAM,eAAe,OAAO;AAE5B,SAAS,SAAS,UAA8C;AACrE,MAAI,OAAO,aAAa,UAAU;AAChC,WAAO,OAAO,OAAO,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AAAA,EAC5D;AACA,SAAO,OAAO,SAAS,YAAY,CAAC;AACtC;;;ACxBO,IAAM,SAAgC;AAAA,EAC3C,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,MACT,OAAO;AAAA,MACP,GAAG;AAAA,MACH,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,MACT,OAAO;AAAA,MACP,GAAG;AAAA,MACH,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,MAAM;AAAA,IACJ,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAEO,SAAS,SAAS,QAAmC;AAC1D,SAAO,OAAO,OAAO,YAAY,CAAC;AACpC;AAEO,SAAS,gBACd,QACA,SACqB;AACrB,SAAO,SAAS,MAAM,GAAG,UAAU,OAAO;AAC5C;;;ACjDA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AACP,SAAS,2BAA2B;AACpC,SAAS,UAAU,SAAS,eAAe;AAW3C,IAAM,YAAY;AAAA,EAChB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,MAAM,MAAM,UAAU;AAAA,MAC9B,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,QAAQ,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,SAAS,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,OAAO,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,MACjC,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,IACrC;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC;AAAA,EACzC;AACF;AAEA,IAAM,aAAwC;AAAA,EAC5C,OAAO;AAAA,EACP,GAAG;AAAA,EACH,KAAK;AACP;AAEO,IAAM,UAAN,MAAc;AAAA,EACX;AAAA,EACA,gBAA2C,oBAAI,IAAI;AAAA,EACnD;AAAA,EAER,YAAY,QAAuB;AACjC,SAAK,SAAS;AAAA,MACZ,GAAG;AAAA,MACH,SAAS,OAAO,WAAW,aAAa;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,gBAAgB,SAAgC;AACtD,UAAM,KAAK,WAAW,KAAK,OAAO;AAClC,QAAI,SAAS,KAAK,cAAc,IAAI,EAAE;AACtC,QAAI,CAAC,QAAQ;AACX,YAAM,QAAQ,WAAW,EAAE;AAC3B,YAAM,YAAY,SAAS,EAAE;AAC7B,YAAM,SACJ,OAAO,KAAK,OAAO,UAAU,KAAK,OAAO,SAAS;AAEpD,eAAS,mBAAmB;AAAA,QAC1B;AAAA,QACA,WAAW,KAAK,UAAU,WAAW,MAAM;AAAA,MAC7C,CAAC;AACD,WAAK,cAAc,IAAI,IAAI,MAAM;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAgC;AACtC,QAAI,CAAC,KAAK,cAAc;AACtB,UAAI,CAAC,KAAK,OAAO,YAAY;AAC3B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,YAAM,UAAU,oBAAoB,KAAK,OAAO,UAAU;AAC1D,YAAM,QAAQ,WAAW,KAAK,OAAO,OAAO;AAC5C,YAAM,YAAY,SAAS,KAAK,OAAO,OAAO;AAC9C,WAAK,eAAe,mBAAmB;AAAA,QACrC;AAAA,QACA;AAAA,QACA,WAAW,KAAK,KAAK,OAAO,UAAU,WAAW,MAAM;AAAA,MACzD,CAAC;AAAA,IACH;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,UAAmB;AACrB,QAAI,CAAC,KAAK,OAAO,YAAY;AAC3B,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AACA,WAAO,oBAAoB,KAAK,OAAO,UAAU,EAAE;AAAA,EACrD;AAAA,EAEA,MAAM,QACJ,OACA,SACkB;AAClB,UAAM,UAAU,SAAS,WAAW,KAAK,OAAO;AAChD,UAAM,UAAU,SAAS,WAAW,KAAK;AACzC,UAAM,SAAS,KAAK,gBAAgB,OAAO;AAE3C,QAAI,MAAM,YAAY,MAAM,OAAO;AACjC,YAAMA,OAAM,MAAM,OAAO,WAAW,EAAE,SAAS,QAAQ,CAAC;AACxD,aAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ,YAAYA,MAAK,EAAE;AAAA,QAC3B,WAAWA;AAAA,QACX,UAAU;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAEA,UAAM,eAAe,gBAAgB,OAAO,OAAO;AACnD,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,SAAS,KAAK,uBAAuB,OAAO,EAAE;AAAA,IAChE;AAEA,UAAM,YAAY,SAAS,KAAK;AAChC,UAAM,MAAM,MAAM,OAAO,aAAa;AAAA,MACpC,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,OAAO;AAAA,IAChB,CAAC;AAED,WAAO;AAAA,MACL,OAAO,UAAU;AAAA,MACjB,QAAQ,UAAU;AAAA,MAClB,QAAQ,YAAY,KAAK,UAAU,QAAQ;AAAA,MAC3C,WAAW;AAAA,MACX,UAAU,UAAU;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,KACJ,OACA,IACA,QACA,SACqB;AACrB,UAAM,UAAU,SAAS,WAAW,KAAK,OAAO;AAChD,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,OAAO,KAAK;AAElB,QAAI,MAAM,YAAY,MAAM,OAAO;AACjC,YAAMC,SAAQ,WAAW,QAAQ,EAAE;AACnC,YAAM,UAAU,oBAAoB,KAAK,OAAO,UAAW;AAC3D,YAAMC,QAAO,MAAM,aAAa,gBAAgB;AAAA,QAC9C;AAAA,QACA;AAAA,QACA,OAAAD;AAAA,QACA,OAAO,WAAW,OAAO;AAAA,MAC3B,CAAC;AACD,aAAO,EAAE,MAAAC,OAAM,MAAM,IAAI,QAAQ,OAAO,OAAO,QAAQ;AAAA,IACzD;AAEA,UAAM,eAAe,gBAAgB,OAAO,OAAO;AACnD,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,SAAS,KAAK,uBAAuB,OAAO,EAAE;AAAA,IAChE;AAEA,UAAM,YAAY,SAAS,KAAK;AAChC,UAAM,QAAQ,WAAW,QAAQ,UAAU,QAAQ;AACnD,UAAM,SAAS,KAAK,gBAAgB,OAAO;AAE3C,UAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,iBAAiB;AAAA,MAChD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,IAAI,KAAK;AAAA,MAChB,SAAS,oBAAoB,KAAK,OAAO,UAAW;AAAA,IACtD,CAAC;AAED,UAAM,OAAO,MAAM,aAAa,cAAc,OAAO;AACrD,WAAO,EAAE,MAAM,MAAM,IAAI,QAAQ,OAAO,UAAU,QAAQ,QAAQ;AAAA,EACpE;AAAA,EAEA,MAAM,KACJ,SACA,UACA,QACA,UACA,SACqB;AACrB,UAAM,UAAU,SAAS,WAAW,KAAK,OAAO;AAChD,UAAM,eAAe,KAAK,gBAAgB;AAC1C,UAAM,SAAS,KAAK,gBAAgB,OAAO;AAC3C,UAAM,SAAS,KAAK;AAEpB,UAAM,iBAAiB,gBAAgB,SAAS,OAAO;AACvD,UAAM,kBAAkB,gBAAgB,UAAU,OAAO;AACzD,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI,MAAM,SAAS,OAAO,uBAAuB,OAAO,EAAE;AAAA,IAClE;AACA,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,MAAM,SAAS,QAAQ,uBAAuB,OAAO,EAAE;AAAA,IACnE;AAEA,UAAM,cAAc,SAAS,OAAO;AACpC,UAAM,YAAY,WAAW,QAAQ,YAAY,QAAQ;AAEzD,UAAM,QAAQ,MAAM,SAAS,SAAS;AAAA,MACpC;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,MACV,QAAQ;AAAA,MACR;AAAA,MACA,UAAU,SAAS;AAAA,IACrB,CAAC;AAED,UAAM,WAAW,MAAM,SAAS,YAAY,KAAK;AAEjD,UAAM,mBAAmB,MAAM,OAAO,aAAa;AAAA,MACjD,SAAS;AAAA,MACT,KAAK;AAAA,MACL,cAAc;AAAA,MACd,MAAM,CAAC,QAAQ,SAAS,EAAE;AAAA,IAC5B,CAAC;AAED,QAAI,mBAAmB,WAAW;AAChC,YAAMC,WAAU,oBAAoB,KAAK,OAAO,UAAW;AAC3D,YAAM,EAAE,SAAS,eAAe,IAAI,MAAM,OAAO,iBAAiB;AAAA,QAChE,SAAS;AAAA,QACT,KAAK;AAAA,QACL,cAAc;AAAA,QACd,MAAM,CAAC,SAAS,IAAI,SAAS;AAAA,QAC7B,SAAAA;AAAA,MACF,CAAC;AACD,YAAM,aAAa,cAAc,cAAc;AAAA,IACjD;AAEA,UAAM,UAAU,oBAAoB,KAAK,OAAO,UAAW;AAC3D,UAAM,OAAO,MAAM,aAAa,gBAAgB;AAAA,MAC9C;AAAA,MACA,IAAI,SAAS;AAAA,MACb,MAAM,SAAS;AAAA,MACf,OAAO,SAAS;AAAA,MAChB,OAAO,WAAW,OAAO;AAAA,IAC3B,CAAC;AAED,UAAM,eAAe,SAAS,QAAQ;AACtC,WAAO;AAAA,MACL;AAAA,MACA,SAAS,YAAY;AAAA,MACrB,UAAU,aAAa;AAAA,MACvB,UAAU;AAAA,MACV,WAAW,YAAY,OAAO,MAAM,WAAW,GAAG,aAAa,QAAQ;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACF;;;ACxSA,IAAM,WAAW;AAgBV,IAAM,eAAN,MAA2C;AAAA,EAChD,OAAO;AAAA,EACC;AAAA,EAER,YAAY,SAA+B;AACzC,SAAK,SAAS,SAAS;AAAA,EACzB;AAAA,EAEA,MAAM,SAAS,QAO6B;AAC1C,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,IAClB;AACA,QAAI,KAAK,QAAQ;AACf,cAAQ,eAAe,IAAI,UAAU,KAAK,MAAM;AAAA,IAClD;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,iBAAiB;AAAA,MACvD,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,SAAS,OAAO;AAAA,QAChB,aAAa;AAAA,UACX;AAAA,YACE,cAAc,OAAO;AAAA,YACrB,QAAQ,OAAO,OAAO,SAAS;AAAA,UACjC;AAAA,QACF;AAAA,QACA,cAAc;AAAA,UACZ;AAAA,YACE,cAAc,OAAO;AAAA,YACrB,YAAY;AAAA,UACd;AAAA,QACF;AAAA,QACA,UAAU,OAAO;AAAA,QACjB,sBAAsB,OAAO,YAAY;AAAA,QACzC,cAAc;AAAA,QACd,SAAS;AAAA,MACX,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,sBAAsB,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACjE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAElC,WAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO,OAAO,SAAS;AAAA,MACjC,aAAa,KAAK,WAAW,CAAC;AAAA,MAC9B,QAAQ;AAAA,MACR,SAAS,OAAO;AAAA,MAChB,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAAA,EAEA,MAAM,YACJ,OACoD;AACpD,UAAM,UAAkC;AAAA,MACtC,gBAAgB;AAAA,IAClB;AACA,QAAI,KAAK,QAAQ;AACf,cAAQ,eAAe,IAAI,UAAU,KAAK,MAAM;AAAA,IAClD;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,iBAAiB;AAAA,MACvD,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,UAAU,MAAM;AAAA,QAChB,QAAQ,MAAM;AAAA,QACd,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,yBAAyB,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IACpE;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAElC,WAAO;AAAA,MACL,IAAI,KAAK,YAAY;AAAA,MACrB,MAAM,KAAK,YAAY;AAAA,MACvB,OAAO,OAAO,KAAK,YAAY,KAAK;AAAA,IACtC;AAAA,EACF;AACF;","names":["raw","value","hash","account"]}
|