moneyos 0.1.1 → 0.2.1
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/cli/index.mjs +38 -19
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +39 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +38 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -109,7 +109,18 @@ function getChain(idOrName) {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// src/core/tokens.ts
|
|
112
|
+
var NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
112
113
|
var tokens = {
|
|
114
|
+
ETH: {
|
|
115
|
+
symbol: "ETH",
|
|
116
|
+
name: "Ether",
|
|
117
|
+
decimals: 18,
|
|
118
|
+
addresses: {
|
|
119
|
+
42161: NATIVE_TOKEN_ADDRESS,
|
|
120
|
+
1: NATIVE_TOKEN_ADDRESS,
|
|
121
|
+
137: NATIVE_TOKEN_ADDRESS
|
|
122
|
+
}
|
|
123
|
+
},
|
|
113
124
|
USDC: {
|
|
114
125
|
symbol: "USDC",
|
|
115
126
|
name: "USD Coin",
|
|
@@ -345,29 +356,32 @@ var MoneyOS = class {
|
|
|
345
356
|
slippage: options?.slippage
|
|
346
357
|
});
|
|
347
358
|
const calldata = await provider.getCalldata(quote);
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
functionName: "allowance",
|
|
352
|
-
args: [sender, calldata.to]
|
|
353
|
-
});
|
|
354
|
-
if (currentAllowance < amountWei) {
|
|
355
|
-
const account2 = privateKeyToAccount2(this.config.privateKey);
|
|
356
|
-
const { request: approveRequest } = await client.simulateContract({
|
|
359
|
+
const isNativeIn = tokenInAddress === NATIVE_TOKEN_ADDRESS;
|
|
360
|
+
if (!isNativeIn) {
|
|
361
|
+
const currentAllowance = await client.readContract({
|
|
357
362
|
address: tokenInAddress,
|
|
358
363
|
abi: ERC20_ABI,
|
|
359
|
-
functionName: "
|
|
360
|
-
args: [calldata.to
|
|
361
|
-
account: account2
|
|
364
|
+
functionName: "allowance",
|
|
365
|
+
args: [sender, calldata.to]
|
|
362
366
|
});
|
|
363
|
-
|
|
367
|
+
if (currentAllowance < amountWei) {
|
|
368
|
+
const account2 = privateKeyToAccount2(this.config.privateKey);
|
|
369
|
+
const { request: approveRequest } = await client.simulateContract({
|
|
370
|
+
address: tokenInAddress,
|
|
371
|
+
abi: ERC20_ABI,
|
|
372
|
+
functionName: "approve",
|
|
373
|
+
args: [calldata.to, amountWei],
|
|
374
|
+
account: account2
|
|
375
|
+
});
|
|
376
|
+
await walletClient.writeContract(approveRequest);
|
|
377
|
+
}
|
|
364
378
|
}
|
|
365
379
|
const account = privateKeyToAccount2(this.config.privateKey);
|
|
366
380
|
const hash = await walletClient.sendTransaction({
|
|
367
381
|
account,
|
|
368
382
|
to: calldata.to,
|
|
369
383
|
data: calldata.data,
|
|
370
|
-
value: calldata.value,
|
|
384
|
+
value: isNativeIn ? amountWei : calldata.value,
|
|
371
385
|
chain: viemChains[chainId]
|
|
372
386
|
});
|
|
373
387
|
const tokenOutInfo = getToken(tokenOut);
|
|
@@ -430,12 +444,16 @@ import { Command as Command4 } from "commander";
|
|
|
430
444
|
|
|
431
445
|
// src/providers/odos.ts
|
|
432
446
|
var ODOS_API = "https://api.odos.xyz";
|
|
447
|
+
var ODOS_NATIVE_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
433
448
|
var OdosProvider = class {
|
|
434
449
|
name = "odos";
|
|
435
450
|
apiKey;
|
|
436
451
|
constructor(options) {
|
|
437
452
|
this.apiKey = options?.apiKey;
|
|
438
453
|
}
|
|
454
|
+
toOdosAddress(address) {
|
|
455
|
+
return address === NATIVE_TOKEN_ADDRESS ? ODOS_NATIVE_ADDRESS : address;
|
|
456
|
+
}
|
|
439
457
|
async getQuote(params) {
|
|
440
458
|
const headers = {
|
|
441
459
|
"Content-Type": "application/json"
|
|
@@ -450,13 +468,13 @@ var OdosProvider = class {
|
|
|
450
468
|
chainId: params.chainId,
|
|
451
469
|
inputTokens: [
|
|
452
470
|
{
|
|
453
|
-
tokenAddress: params.tokenIn,
|
|
471
|
+
tokenAddress: this.toOdosAddress(params.tokenIn),
|
|
454
472
|
amount: params.amount.toString()
|
|
455
473
|
}
|
|
456
474
|
],
|
|
457
475
|
outputTokens: [
|
|
458
476
|
{
|
|
459
|
-
tokenAddress: params.tokenOut,
|
|
477
|
+
tokenAddress: this.toOdosAddress(params.tokenOut),
|
|
460
478
|
proportion: 1
|
|
461
479
|
}
|
|
462
480
|
],
|
|
@@ -478,7 +496,8 @@ var OdosProvider = class {
|
|
|
478
496
|
expectedOut: data.outAmounts[0],
|
|
479
497
|
router: "",
|
|
480
498
|
chainId: params.chainId,
|
|
481
|
-
pathId: data.pathId
|
|
499
|
+
pathId: data.pathId,
|
|
500
|
+
sender: params.sender
|
|
482
501
|
};
|
|
483
502
|
}
|
|
484
503
|
async getCalldata(quote) {
|
|
@@ -492,7 +511,7 @@ var OdosProvider = class {
|
|
|
492
511
|
method: "POST",
|
|
493
512
|
headers,
|
|
494
513
|
body: JSON.stringify({
|
|
495
|
-
userAddr: quote.
|
|
514
|
+
userAddr: quote.sender,
|
|
496
515
|
pathId: quote.pathId,
|
|
497
516
|
simulate: false
|
|
498
517
|
})
|
|
@@ -538,7 +557,7 @@ var swapCommand = new Command4("swap").description("Swap tokens").argument("<amo
|
|
|
538
557
|
});
|
|
539
558
|
|
|
540
559
|
// src/cli/version.ts
|
|
541
|
-
var version = "0.
|
|
560
|
+
var version = "0.2.1";
|
|
542
561
|
|
|
543
562
|
// src/cli/index.ts
|
|
544
563
|
var program = new Command5();
|
package/dist/cli/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/init.ts","../../src/cli/config.ts","../../src/cli/commands/balance.ts","../../src/core/client.ts","../../src/core/chains.ts","../../src/core/tokens.ts","../../src/cli/commands/send.ts","../../src/cli/commands/swap.ts","../../src/providers/odos.ts","../../src/cli/version.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { balanceCommand } from \"./commands/balance.js\";\nimport { sendCommand } from \"./commands/send.js\";\nimport { swapCommand } from \"./commands/swap.js\";\nimport { version } from \"./version.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"moneyos\")\n .description(\"The operating system for money\")\n .version(version);\n\nprogram.addCommand(initCommand);\nprogram.addCommand(balanceCommand);\nprogram.addCommand(sendCommand);\nprogram.addCommand(swapCommand);\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\nimport { loadConfig, saveConfig, getConfigPath } from \"../config.js\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize MoneyOS with a new or existing account\")\n .option(\"-k, --key <privateKey>\", \"Import an existing private key\")\n .option(\"--chain <chainId>\", \"Default chain ID (default: 42161 Arbitrum)\")\n .option(\"--rpc <url>\", \"Custom RPC URL\")\n .action(async (options) => {\n const existing = loadConfig();\n\n if (existing.privateKey && !options.key) {\n const account = privateKeyToAccount(existing.privateKey);\n console.log(`Already initialized.`);\n console.log(`Address: ${account.address}`);\n console.log(`Config: ${getConfigPath()}`);\n console.log(`\\nTo reinitialize, run: moneyos init --key <privateKey>`);\n return;\n }\n\n const privateKey = options.key ?? generatePrivateKey();\n const account = privateKeyToAccount(privateKey);\n\n const config = {\n ...existing,\n privateKey,\n chainId: options.chain ? parseInt(options.chain) : existing.chainId ?? 42161,\n rpcUrl: options.rpc ?? existing.rpcUrl,\n };\n\n saveConfig(config);\n\n console.log(`MoneyOS initialized.`);\n console.log(`Address: ${account.address}`);\n console.log(`Config: ${getConfigPath()}`);\n\n if (!options.key) {\n console.log(`\\nThis is a new account. Fund it before sending transactions.`);\n }\n });\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { Hex } from \"viem\";\n\nconst CONFIG_DIR = join(homedir(), \".moneyos\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nexport interface CLIConfig {\n chainId?: number;\n rpcUrl?: string;\n privateKey?: Hex;\n}\n\nexport function loadConfig(): CLIConfig {\n if (!existsSync(CONFIG_FILE)) {\n return {};\n }\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw) as CLIConfig;\n}\n\nexport function saveConfig(config: CLIConfig): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n }\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), {\n mode: 0o600,\n });\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","import { Command } from \"commander\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { loadConfig } from \"../config.js\";\nimport type { Address } from \"viem\";\n\nexport const balanceCommand = new Command(\"balance\")\n .description(\"Check token balance\")\n .argument(\"<token>\", \"Token symbol (e.g. USDC, ETH, RYZE)\")\n .option(\"-a, --address <address>\", \"Address to check (defaults to your own)\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .action(async (token: string, options) => {\n const config = loadConfig();\n const chainId = options.chain ? parseInt(options.chain) : config.chainId;\n\n const moneyos = new MoneyOS({\n chainId: chainId ?? 42161,\n rpcUrl: config.rpcUrl,\n privateKey: options.address ? undefined : config.privateKey,\n });\n\n const address = options.address as Address | undefined;\n const result = await moneyos.balance(token, {\n address,\n chainId,\n });\n\n console.log(`${result.amount} ${result.symbol}`);\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 { 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 { Command } from \"commander\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { loadConfig } from \"../config.js\";\nimport { getChain } from \"../../core/chains.js\";\nimport type { Address } from \"viem\";\n\nexport const sendCommand = new Command(\"send\")\n .description(\"Send tokens to an address\")\n .argument(\"<amount>\", \"Amount to send (e.g. 10)\")\n .argument(\"<token>\", \"Token symbol (e.g. USDC, ETH, RYZE)\")\n .argument(\"<to>\", \"Recipient address\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .action(async (amount: string, token: string, to: string, options) => {\n const config = loadConfig();\n\n if (!config.privateKey) {\n console.error(\n \"No private key configured. Run: moneyos init\",\n );\n process.exit(1);\n }\n\n const chainId = options.chain\n ? parseInt(options.chain)\n : config.chainId ?? 42161;\n\n const moneyos = new MoneyOS({\n chainId,\n rpcUrl: config.rpcUrl,\n privateKey: config.privateKey,\n });\n\n const chain = getChain(chainId);\n console.log(\n `Sending ${amount} ${token.toUpperCase()} to ${to} on ${chain?.name ?? chainId}...`,\n );\n\n const result = await moneyos.send(token, to as Address, amount, {\n chainId,\n });\n\n console.log(`Sent. tx: ${result.hash}`);\n });\n","import { Command } from \"commander\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { OdosProvider } from \"../../providers/odos.js\";\nimport { loadConfig } from \"../config.js\";\nimport { getChain } from \"../../core/chains.js\";\n\nexport const swapCommand = new Command(\"swap\")\n .description(\"Swap tokens\")\n .argument(\"<amount>\", \"Amount to swap (e.g. 100)\")\n .argument(\"<tokenIn>\", \"Token to sell (e.g. USDC)\")\n .argument(\"<tokenOut>\", \"Token to buy (e.g. RYZE)\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .option(\"-s, --slippage <percent>\", \"Slippage tolerance in percent (default: 1)\")\n .action(async (amount: string, tokenIn: string, tokenOut: string, options) => {\n const config = loadConfig();\n\n if (!config.privateKey) {\n console.error(\"No private key configured. Run: moneyos init\");\n process.exit(1);\n }\n\n const chainId = options.chain\n ? parseInt(options.chain)\n : config.chainId ?? 42161;\n\n const moneyos = new MoneyOS({\n chainId,\n rpcUrl: config.rpcUrl,\n privateKey: config.privateKey,\n });\n\n const provider = new OdosProvider();\n const chain = getChain(chainId);\n const slippage = options.slippage ? parseFloat(options.slippage) : undefined;\n\n console.log(\n `Swapping ${amount} ${tokenIn.toUpperCase()} \\u2192 ${tokenOut.toUpperCase()} on ${chain?.name ?? chainId}...`,\n );\n\n const result = await moneyos.swap(tokenIn, tokenOut, amount, provider, {\n chainId,\n slippage,\n });\n\n console.log(`Swapped. Expected: ~${result.amountOut} ${result.tokenOut}`);\n console.log(`tx: ${result.hash}`);\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","export const version = \"0.1.1\";\n"],"mappings":"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","names":["Command","account","Command","privateKeyToAccount","privateKeyToAccount","raw","value","hash","account","Command","Command","Command","Command","Command","Command"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/init.ts","../../src/cli/config.ts","../../src/cli/commands/balance.ts","../../src/core/client.ts","../../src/core/chains.ts","../../src/core/tokens.ts","../../src/cli/commands/send.ts","../../src/cli/commands/swap.ts","../../src/providers/odos.ts","../../src/cli/version.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { initCommand } from \"./commands/init.js\";\nimport { balanceCommand } from \"./commands/balance.js\";\nimport { sendCommand } from \"./commands/send.js\";\nimport { swapCommand } from \"./commands/swap.js\";\nimport { version } from \"./version.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"moneyos\")\n .description(\"The operating system for money\")\n .version(version);\n\nprogram.addCommand(initCommand);\nprogram.addCommand(balanceCommand);\nprogram.addCommand(sendCommand);\nprogram.addCommand(swapCommand);\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\nimport { loadConfig, saveConfig, getConfigPath } from \"../config.js\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Initialize MoneyOS with a new or existing account\")\n .option(\"-k, --key <privateKey>\", \"Import an existing private key\")\n .option(\"--chain <chainId>\", \"Default chain ID (default: 42161 Arbitrum)\")\n .option(\"--rpc <url>\", \"Custom RPC URL\")\n .action(async (options) => {\n const existing = loadConfig();\n\n if (existing.privateKey && !options.key) {\n const account = privateKeyToAccount(existing.privateKey);\n console.log(`Already initialized.`);\n console.log(`Address: ${account.address}`);\n console.log(`Config: ${getConfigPath()}`);\n console.log(`\\nTo reinitialize, run: moneyos init --key <privateKey>`);\n return;\n }\n\n const privateKey = options.key ?? generatePrivateKey();\n const account = privateKeyToAccount(privateKey);\n\n const config = {\n ...existing,\n privateKey,\n chainId: options.chain ? parseInt(options.chain) : existing.chainId ?? 42161,\n rpcUrl: options.rpc ?? existing.rpcUrl,\n };\n\n saveConfig(config);\n\n console.log(`MoneyOS initialized.`);\n console.log(`Address: ${account.address}`);\n console.log(`Config: ${getConfigPath()}`);\n\n if (!options.key) {\n console.log(`\\nThis is a new account. Fund it before sending transactions.`);\n }\n });\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { Hex } from \"viem\";\n\nconst CONFIG_DIR = join(homedir(), \".moneyos\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\nexport interface CLIConfig {\n chainId?: number;\n rpcUrl?: string;\n privateKey?: Hex;\n}\n\nexport function loadConfig(): CLIConfig {\n if (!existsSync(CONFIG_FILE)) {\n return {};\n }\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw) as CLIConfig;\n}\n\nexport function saveConfig(config: CLIConfig): void {\n if (!existsSync(CONFIG_DIR)) {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n }\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), {\n mode: 0o600,\n });\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","import { Command } from \"commander\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { loadConfig } from \"../config.js\";\nimport type { Address } from \"viem\";\n\nexport const balanceCommand = new Command(\"balance\")\n .description(\"Check token balance\")\n .argument(\"<token>\", \"Token symbol (e.g. USDC, ETH, RYZE)\")\n .option(\"-a, --address <address>\", \"Address to check (defaults to your own)\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .action(async (token: string, options) => {\n const config = loadConfig();\n const chainId = options.chain ? parseInt(options.chain) : config.chainId;\n\n const moneyos = new MoneyOS({\n chainId: chainId ?? 42161,\n rpcUrl: config.rpcUrl,\n privateKey: options.address ? undefined : config.privateKey,\n });\n\n const address = options.address as Address | undefined;\n const result = await moneyos.balance(token, {\n address,\n chainId,\n });\n\n console.log(`${result.amount} ${result.symbol}`);\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, NATIVE_TOKEN_ADDRESS } 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 isNativeIn = tokenInAddress === NATIVE_TOKEN_ADDRESS;\n\n if (!isNativeIn) {\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\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: isNativeIn ? amountWei : 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 { 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 NATIVE_TOKEN_ADDRESS =\n \"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\" as Address;\n\nexport const tokens: Record<string, Token> = {\n ETH: {\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n addresses: {\n 42161: NATIVE_TOKEN_ADDRESS,\n 1: NATIVE_TOKEN_ADDRESS,\n 137: NATIVE_TOKEN_ADDRESS,\n },\n },\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 { Command } from \"commander\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { loadConfig } from \"../config.js\";\nimport { getChain } from \"../../core/chains.js\";\nimport type { Address } from \"viem\";\n\nexport const sendCommand = new Command(\"send\")\n .description(\"Send tokens to an address\")\n .argument(\"<amount>\", \"Amount to send (e.g. 10)\")\n .argument(\"<token>\", \"Token symbol (e.g. USDC, ETH, RYZE)\")\n .argument(\"<to>\", \"Recipient address\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .action(async (amount: string, token: string, to: string, options) => {\n const config = loadConfig();\n\n if (!config.privateKey) {\n console.error(\n \"No private key configured. Run: moneyos init\",\n );\n process.exit(1);\n }\n\n const chainId = options.chain\n ? parseInt(options.chain)\n : config.chainId ?? 42161;\n\n const moneyos = new MoneyOS({\n chainId,\n rpcUrl: config.rpcUrl,\n privateKey: config.privateKey,\n });\n\n const chain = getChain(chainId);\n console.log(\n `Sending ${amount} ${token.toUpperCase()} to ${to} on ${chain?.name ?? chainId}...`,\n );\n\n const result = await moneyos.send(token, to as Address, amount, {\n chainId,\n });\n\n console.log(`Sent. tx: ${result.hash}`);\n });\n","import { Command } from \"commander\";\nimport { MoneyOS } from \"../../core/client.js\";\nimport { OdosProvider } from \"../../providers/odos.js\";\nimport { loadConfig } from \"../config.js\";\nimport { getChain } from \"../../core/chains.js\";\n\nexport const swapCommand = new Command(\"swap\")\n .description(\"Swap tokens\")\n .argument(\"<amount>\", \"Amount to swap (e.g. 100)\")\n .argument(\"<tokenIn>\", \"Token to sell (e.g. USDC)\")\n .argument(\"<tokenOut>\", \"Token to buy (e.g. RYZE)\")\n .option(\"-c, --chain <chainId>\", \"Chain ID (default: 42161 Arbitrum)\")\n .option(\"-s, --slippage <percent>\", \"Slippage tolerance in percent (default: 1)\")\n .action(async (amount: string, tokenIn: string, tokenOut: string, options) => {\n const config = loadConfig();\n\n if (!config.privateKey) {\n console.error(\"No private key configured. Run: moneyos init\");\n process.exit(1);\n }\n\n const chainId = options.chain\n ? parseInt(options.chain)\n : config.chainId ?? 42161;\n\n const moneyos = new MoneyOS({\n chainId,\n rpcUrl: config.rpcUrl,\n privateKey: config.privateKey,\n });\n\n const provider = new OdosProvider();\n const chain = getChain(chainId);\n const slippage = options.slippage ? parseFloat(options.slippage) : undefined;\n\n console.log(\n `Swapping ${amount} ${tokenIn.toUpperCase()} \\u2192 ${tokenOut.toUpperCase()} on ${chain?.name ?? chainId}...`,\n );\n\n const result = await moneyos.swap(tokenIn, tokenOut, amount, provider, {\n chainId,\n slippage,\n });\n\n console.log(`Swapped. Expected: ~${result.amountOut} ${result.tokenOut}`);\n console.log(`tx: ${result.hash}`);\n });\n","import type { Address, Hex } from \"viem\";\nimport type { SwapProvider, SwapQuote } from \"../core/types.js\";\nimport { NATIVE_TOKEN_ADDRESS } from \"../core/tokens.js\";\n\nconst ODOS_API = \"https://api.odos.xyz\";\nconst ODOS_NATIVE_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\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 private toOdosAddress(address: Address): Address {\n return address === NATIVE_TOKEN_ADDRESS ? ODOS_NATIVE_ADDRESS : address;\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; sender: Address }> {\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: this.toOdosAddress(params.tokenIn),\n amount: params.amount.toString(),\n },\n ],\n outputTokens: [\n {\n tokenAddress: this.toOdosAddress(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 sender: params.sender,\n };\n }\n\n async getCalldata(\n quote: SwapQuote & { pathId: string; sender: Address },\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.sender,\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","export const version = \"0.2.1\";\n"],"mappings":"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","names":["Command","account","Command","privateKeyToAccount","privateKeyToAccount","raw","value","hash","account","Command","Command","Command","Command","Command","Command"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -99,6 +99,7 @@ interface Token {
|
|
|
99
99
|
decimals: number;
|
|
100
100
|
addresses: Record<number, Address>;
|
|
101
101
|
}
|
|
102
|
+
declare const NATIVE_TOKEN_ADDRESS: Address;
|
|
102
103
|
declare const tokens: Record<string, Token>;
|
|
103
104
|
declare function getToken(symbol: string): Token | undefined;
|
|
104
105
|
declare function getTokenAddress(symbol: string, chainId: number): Address | undefined;
|
|
@@ -109,6 +110,7 @@ declare class OdosProvider implements SwapProvider {
|
|
|
109
110
|
constructor(options?: {
|
|
110
111
|
apiKey?: string;
|
|
111
112
|
});
|
|
113
|
+
private toOdosAddress;
|
|
112
114
|
getQuote(params: {
|
|
113
115
|
chainId: number;
|
|
114
116
|
tokenIn: Address;
|
|
@@ -118,9 +120,11 @@ declare class OdosProvider implements SwapProvider {
|
|
|
118
120
|
slippage?: number;
|
|
119
121
|
}): Promise<SwapQuote & {
|
|
120
122
|
pathId: string;
|
|
123
|
+
sender: Address;
|
|
121
124
|
}>;
|
|
122
125
|
getCalldata(quote: SwapQuote & {
|
|
123
126
|
pathId: string;
|
|
127
|
+
sender: Address;
|
|
124
128
|
}): Promise<{
|
|
125
129
|
to: Address;
|
|
126
130
|
data: Hex;
|
|
@@ -128,4 +132,4 @@ declare class OdosProvider implements SwapProvider {
|
|
|
128
132
|
}>;
|
|
129
133
|
}
|
|
130
134
|
|
|
131
|
-
export { type Balance, type Chain, MoneyOS, type MoneyOSConfig, OdosProvider, type SendResult, type SwapProvider, type SwapQuote, type SwapResult, type Token, chains, defaultChain, getChain, getToken, getTokenAddress, tokens };
|
|
135
|
+
export { type Balance, type Chain, MoneyOS, type MoneyOSConfig, NATIVE_TOKEN_ADDRESS, OdosProvider, type SendResult, type SwapProvider, type SwapQuote, type SwapResult, type Token, chains, defaultChain, getChain, getToken, getTokenAddress, tokens };
|
package/dist/index.d.ts
CHANGED
|
@@ -99,6 +99,7 @@ interface Token {
|
|
|
99
99
|
decimals: number;
|
|
100
100
|
addresses: Record<number, Address>;
|
|
101
101
|
}
|
|
102
|
+
declare const NATIVE_TOKEN_ADDRESS: Address;
|
|
102
103
|
declare const tokens: Record<string, Token>;
|
|
103
104
|
declare function getToken(symbol: string): Token | undefined;
|
|
104
105
|
declare function getTokenAddress(symbol: string, chainId: number): Address | undefined;
|
|
@@ -109,6 +110,7 @@ declare class OdosProvider implements SwapProvider {
|
|
|
109
110
|
constructor(options?: {
|
|
110
111
|
apiKey?: string;
|
|
111
112
|
});
|
|
113
|
+
private toOdosAddress;
|
|
112
114
|
getQuote(params: {
|
|
113
115
|
chainId: number;
|
|
114
116
|
tokenIn: Address;
|
|
@@ -118,9 +120,11 @@ declare class OdosProvider implements SwapProvider {
|
|
|
118
120
|
slippage?: number;
|
|
119
121
|
}): Promise<SwapQuote & {
|
|
120
122
|
pathId: string;
|
|
123
|
+
sender: Address;
|
|
121
124
|
}>;
|
|
122
125
|
getCalldata(quote: SwapQuote & {
|
|
123
126
|
pathId: string;
|
|
127
|
+
sender: Address;
|
|
124
128
|
}): Promise<{
|
|
125
129
|
to: Address;
|
|
126
130
|
data: Hex;
|
|
@@ -128,4 +132,4 @@ declare class OdosProvider implements SwapProvider {
|
|
|
128
132
|
}>;
|
|
129
133
|
}
|
|
130
134
|
|
|
131
|
-
export { type Balance, type Chain, MoneyOS, type MoneyOSConfig, OdosProvider, type SendResult, type SwapProvider, type SwapQuote, type SwapResult, type Token, chains, defaultChain, getChain, getToken, getTokenAddress, tokens };
|
|
135
|
+
export { type Balance, type Chain, MoneyOS, type MoneyOSConfig, NATIVE_TOKEN_ADDRESS, OdosProvider, type SendResult, type SwapProvider, type SwapQuote, type SwapResult, type Token, chains, defaultChain, getChain, getToken, getTokenAddress, tokens };
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
MoneyOS: () => MoneyOS,
|
|
24
|
+
NATIVE_TOKEN_ADDRESS: () => NATIVE_TOKEN_ADDRESS,
|
|
24
25
|
OdosProvider: () => OdosProvider,
|
|
25
26
|
chains: () => chains,
|
|
26
27
|
defaultChain: () => defaultChain,
|
|
@@ -69,7 +70,18 @@ function getChain(idOrName) {
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
// src/core/tokens.ts
|
|
73
|
+
var NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
72
74
|
var tokens = {
|
|
75
|
+
ETH: {
|
|
76
|
+
symbol: "ETH",
|
|
77
|
+
name: "Ether",
|
|
78
|
+
decimals: 18,
|
|
79
|
+
addresses: {
|
|
80
|
+
42161: NATIVE_TOKEN_ADDRESS,
|
|
81
|
+
1: NATIVE_TOKEN_ADDRESS,
|
|
82
|
+
137: NATIVE_TOKEN_ADDRESS
|
|
83
|
+
}
|
|
84
|
+
},
|
|
73
85
|
USDC: {
|
|
74
86
|
symbol: "USDC",
|
|
75
87
|
name: "USD Coin",
|
|
@@ -305,29 +317,32 @@ var MoneyOS = class {
|
|
|
305
317
|
slippage: options?.slippage
|
|
306
318
|
});
|
|
307
319
|
const calldata = await provider.getCalldata(quote);
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
functionName: "allowance",
|
|
312
|
-
args: [sender, calldata.to]
|
|
313
|
-
});
|
|
314
|
-
if (currentAllowance < amountWei) {
|
|
315
|
-
const account2 = (0, import_accounts.privateKeyToAccount)(this.config.privateKey);
|
|
316
|
-
const { request: approveRequest } = await client.simulateContract({
|
|
320
|
+
const isNativeIn = tokenInAddress === NATIVE_TOKEN_ADDRESS;
|
|
321
|
+
if (!isNativeIn) {
|
|
322
|
+
const currentAllowance = await client.readContract({
|
|
317
323
|
address: tokenInAddress,
|
|
318
324
|
abi: ERC20_ABI,
|
|
319
|
-
functionName: "
|
|
320
|
-
args: [calldata.to
|
|
321
|
-
account: account2
|
|
325
|
+
functionName: "allowance",
|
|
326
|
+
args: [sender, calldata.to]
|
|
322
327
|
});
|
|
323
|
-
|
|
328
|
+
if (currentAllowance < amountWei) {
|
|
329
|
+
const account2 = (0, import_accounts.privateKeyToAccount)(this.config.privateKey);
|
|
330
|
+
const { request: approveRequest } = await client.simulateContract({
|
|
331
|
+
address: tokenInAddress,
|
|
332
|
+
abi: ERC20_ABI,
|
|
333
|
+
functionName: "approve",
|
|
334
|
+
args: [calldata.to, amountWei],
|
|
335
|
+
account: account2
|
|
336
|
+
});
|
|
337
|
+
await walletClient.writeContract(approveRequest);
|
|
338
|
+
}
|
|
324
339
|
}
|
|
325
340
|
const account = (0, import_accounts.privateKeyToAccount)(this.config.privateKey);
|
|
326
341
|
const hash = await walletClient.sendTransaction({
|
|
327
342
|
account,
|
|
328
343
|
to: calldata.to,
|
|
329
344
|
data: calldata.data,
|
|
330
|
-
value: calldata.value,
|
|
345
|
+
value: isNativeIn ? amountWei : calldata.value,
|
|
331
346
|
chain: viemChains[chainId]
|
|
332
347
|
});
|
|
333
348
|
const tokenOutInfo = getToken(tokenOut);
|
|
@@ -344,12 +359,16 @@ var MoneyOS = class {
|
|
|
344
359
|
|
|
345
360
|
// src/providers/odos.ts
|
|
346
361
|
var ODOS_API = "https://api.odos.xyz";
|
|
362
|
+
var ODOS_NATIVE_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
347
363
|
var OdosProvider = class {
|
|
348
364
|
name = "odos";
|
|
349
365
|
apiKey;
|
|
350
366
|
constructor(options) {
|
|
351
367
|
this.apiKey = options?.apiKey;
|
|
352
368
|
}
|
|
369
|
+
toOdosAddress(address) {
|
|
370
|
+
return address === NATIVE_TOKEN_ADDRESS ? ODOS_NATIVE_ADDRESS : address;
|
|
371
|
+
}
|
|
353
372
|
async getQuote(params) {
|
|
354
373
|
const headers = {
|
|
355
374
|
"Content-Type": "application/json"
|
|
@@ -364,13 +383,13 @@ var OdosProvider = class {
|
|
|
364
383
|
chainId: params.chainId,
|
|
365
384
|
inputTokens: [
|
|
366
385
|
{
|
|
367
|
-
tokenAddress: params.tokenIn,
|
|
386
|
+
tokenAddress: this.toOdosAddress(params.tokenIn),
|
|
368
387
|
amount: params.amount.toString()
|
|
369
388
|
}
|
|
370
389
|
],
|
|
371
390
|
outputTokens: [
|
|
372
391
|
{
|
|
373
|
-
tokenAddress: params.tokenOut,
|
|
392
|
+
tokenAddress: this.toOdosAddress(params.tokenOut),
|
|
374
393
|
proportion: 1
|
|
375
394
|
}
|
|
376
395
|
],
|
|
@@ -392,7 +411,8 @@ var OdosProvider = class {
|
|
|
392
411
|
expectedOut: data.outAmounts[0],
|
|
393
412
|
router: "",
|
|
394
413
|
chainId: params.chainId,
|
|
395
|
-
pathId: data.pathId
|
|
414
|
+
pathId: data.pathId,
|
|
415
|
+
sender: params.sender
|
|
396
416
|
};
|
|
397
417
|
}
|
|
398
418
|
async getCalldata(quote) {
|
|
@@ -406,7 +426,7 @@ var OdosProvider = class {
|
|
|
406
426
|
method: "POST",
|
|
407
427
|
headers,
|
|
408
428
|
body: JSON.stringify({
|
|
409
|
-
userAddr: quote.
|
|
429
|
+
userAddr: quote.sender,
|
|
410
430
|
pathId: quote.pathId,
|
|
411
431
|
simulate: false
|
|
412
432
|
})
|
|
@@ -426,6 +446,7 @@ var OdosProvider = class {
|
|
|
426
446
|
// Annotate the CommonJS export names for ESM import in node:
|
|
427
447
|
0 && (module.exports = {
|
|
428
448
|
MoneyOS,
|
|
449
|
+
NATIVE_TOKEN_ADDRESS,
|
|
429
450
|
OdosProvider,
|
|
430
451
|
chains,
|
|
431
452
|
defaultChain,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/client.ts","../src/core/chains.ts","../src/core/tokens.ts","../src/providers/odos.ts"],"sourcesContent":["export { MoneyOS } from \"./core/client.js\";\nexport { chains, defaultChain, getChain } from \"./core/chains.js\";\nexport { tokens, getToken, getTokenAddress } from \"./core/tokens.js\";\nexport { OdosProvider } from \"./providers/odos.js\";\n\nexport type {\n MoneyOSConfig,\n Balance,\n SendResult,\n SwapQuote,\n SwapResult,\n SwapProvider,\n Chain,\n} from \"./core/types.js\";\nexport type { Token } from \"./core/tokens.js\";\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 { 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 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":"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","names":["raw","value","hash","account"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/client.ts","../src/core/chains.ts","../src/core/tokens.ts","../src/providers/odos.ts"],"sourcesContent":["export { MoneyOS } from \"./core/client.js\";\nexport { chains, defaultChain, getChain } from \"./core/chains.js\";\nexport { tokens, getToken, getTokenAddress, NATIVE_TOKEN_ADDRESS } from \"./core/tokens.js\";\nexport { OdosProvider } from \"./providers/odos.js\";\n\nexport type {\n MoneyOSConfig,\n Balance,\n SendResult,\n SwapQuote,\n SwapResult,\n SwapProvider,\n Chain,\n} from \"./core/types.js\";\nexport type { Token } from \"./core/tokens.js\";\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, NATIVE_TOKEN_ADDRESS } 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 isNativeIn = tokenInAddress === NATIVE_TOKEN_ADDRESS;\n\n if (!isNativeIn) {\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\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: isNativeIn ? amountWei : 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 { 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 NATIVE_TOKEN_ADDRESS =\n \"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\" as Address;\n\nexport const tokens: Record<string, Token> = {\n ETH: {\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n addresses: {\n 42161: NATIVE_TOKEN_ADDRESS,\n 1: NATIVE_TOKEN_ADDRESS,\n 137: NATIVE_TOKEN_ADDRESS,\n },\n },\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 type { Address, Hex } from \"viem\";\nimport type { SwapProvider, SwapQuote } from \"../core/types.js\";\nimport { NATIVE_TOKEN_ADDRESS } from \"../core/tokens.js\";\n\nconst ODOS_API = \"https://api.odos.xyz\";\nconst ODOS_NATIVE_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\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 private toOdosAddress(address: Address): Address {\n return address === NATIVE_TOKEN_ADDRESS ? ODOS_NATIVE_ADDRESS : address;\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; sender: Address }> {\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: this.toOdosAddress(params.tokenIn),\n amount: params.amount.toString(),\n },\n ],\n outputTokens: [\n {\n tokenAddress: this.toOdosAddress(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 sender: params.sender,\n };\n }\n\n async getCalldata(\n quote: SwapQuote & { pathId: string; sender: Address },\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.sender,\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":"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","names":["raw","value","hash","account"]}
|
package/dist/index.mjs
CHANGED
|
@@ -42,7 +42,18 @@ function getChain(idOrName) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// src/core/tokens.ts
|
|
45
|
+
var NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
45
46
|
var tokens = {
|
|
47
|
+
ETH: {
|
|
48
|
+
symbol: "ETH",
|
|
49
|
+
name: "Ether",
|
|
50
|
+
decimals: 18,
|
|
51
|
+
addresses: {
|
|
52
|
+
42161: NATIVE_TOKEN_ADDRESS,
|
|
53
|
+
1: NATIVE_TOKEN_ADDRESS,
|
|
54
|
+
137: NATIVE_TOKEN_ADDRESS
|
|
55
|
+
}
|
|
56
|
+
},
|
|
46
57
|
USDC: {
|
|
47
58
|
symbol: "USDC",
|
|
48
59
|
name: "USD Coin",
|
|
@@ -278,29 +289,32 @@ var MoneyOS = class {
|
|
|
278
289
|
slippage: options?.slippage
|
|
279
290
|
});
|
|
280
291
|
const calldata = await provider.getCalldata(quote);
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
functionName: "allowance",
|
|
285
|
-
args: [sender, calldata.to]
|
|
286
|
-
});
|
|
287
|
-
if (currentAllowance < amountWei) {
|
|
288
|
-
const account2 = privateKeyToAccount(this.config.privateKey);
|
|
289
|
-
const { request: approveRequest } = await client.simulateContract({
|
|
292
|
+
const isNativeIn = tokenInAddress === NATIVE_TOKEN_ADDRESS;
|
|
293
|
+
if (!isNativeIn) {
|
|
294
|
+
const currentAllowance = await client.readContract({
|
|
290
295
|
address: tokenInAddress,
|
|
291
296
|
abi: ERC20_ABI,
|
|
292
|
-
functionName: "
|
|
293
|
-
args: [calldata.to
|
|
294
|
-
account: account2
|
|
297
|
+
functionName: "allowance",
|
|
298
|
+
args: [sender, calldata.to]
|
|
295
299
|
});
|
|
296
|
-
|
|
300
|
+
if (currentAllowance < amountWei) {
|
|
301
|
+
const account2 = privateKeyToAccount(this.config.privateKey);
|
|
302
|
+
const { request: approveRequest } = await client.simulateContract({
|
|
303
|
+
address: tokenInAddress,
|
|
304
|
+
abi: ERC20_ABI,
|
|
305
|
+
functionName: "approve",
|
|
306
|
+
args: [calldata.to, amountWei],
|
|
307
|
+
account: account2
|
|
308
|
+
});
|
|
309
|
+
await walletClient.writeContract(approveRequest);
|
|
310
|
+
}
|
|
297
311
|
}
|
|
298
312
|
const account = privateKeyToAccount(this.config.privateKey);
|
|
299
313
|
const hash = await walletClient.sendTransaction({
|
|
300
314
|
account,
|
|
301
315
|
to: calldata.to,
|
|
302
316
|
data: calldata.data,
|
|
303
|
-
value: calldata.value,
|
|
317
|
+
value: isNativeIn ? amountWei : calldata.value,
|
|
304
318
|
chain: viemChains[chainId]
|
|
305
319
|
});
|
|
306
320
|
const tokenOutInfo = getToken(tokenOut);
|
|
@@ -317,12 +331,16 @@ var MoneyOS = class {
|
|
|
317
331
|
|
|
318
332
|
// src/providers/odos.ts
|
|
319
333
|
var ODOS_API = "https://api.odos.xyz";
|
|
334
|
+
var ODOS_NATIVE_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
320
335
|
var OdosProvider = class {
|
|
321
336
|
name = "odos";
|
|
322
337
|
apiKey;
|
|
323
338
|
constructor(options) {
|
|
324
339
|
this.apiKey = options?.apiKey;
|
|
325
340
|
}
|
|
341
|
+
toOdosAddress(address) {
|
|
342
|
+
return address === NATIVE_TOKEN_ADDRESS ? ODOS_NATIVE_ADDRESS : address;
|
|
343
|
+
}
|
|
326
344
|
async getQuote(params) {
|
|
327
345
|
const headers = {
|
|
328
346
|
"Content-Type": "application/json"
|
|
@@ -337,13 +355,13 @@ var OdosProvider = class {
|
|
|
337
355
|
chainId: params.chainId,
|
|
338
356
|
inputTokens: [
|
|
339
357
|
{
|
|
340
|
-
tokenAddress: params.tokenIn,
|
|
358
|
+
tokenAddress: this.toOdosAddress(params.tokenIn),
|
|
341
359
|
amount: params.amount.toString()
|
|
342
360
|
}
|
|
343
361
|
],
|
|
344
362
|
outputTokens: [
|
|
345
363
|
{
|
|
346
|
-
tokenAddress: params.tokenOut,
|
|
364
|
+
tokenAddress: this.toOdosAddress(params.tokenOut),
|
|
347
365
|
proportion: 1
|
|
348
366
|
}
|
|
349
367
|
],
|
|
@@ -365,7 +383,8 @@ var OdosProvider = class {
|
|
|
365
383
|
expectedOut: data.outAmounts[0],
|
|
366
384
|
router: "",
|
|
367
385
|
chainId: params.chainId,
|
|
368
|
-
pathId: data.pathId
|
|
386
|
+
pathId: data.pathId,
|
|
387
|
+
sender: params.sender
|
|
369
388
|
};
|
|
370
389
|
}
|
|
371
390
|
async getCalldata(quote) {
|
|
@@ -379,7 +398,7 @@ var OdosProvider = class {
|
|
|
379
398
|
method: "POST",
|
|
380
399
|
headers,
|
|
381
400
|
body: JSON.stringify({
|
|
382
|
-
userAddr: quote.
|
|
401
|
+
userAddr: quote.sender,
|
|
383
402
|
pathId: quote.pathId,
|
|
384
403
|
simulate: false
|
|
385
404
|
})
|
|
@@ -398,6 +417,7 @@ var OdosProvider = class {
|
|
|
398
417
|
};
|
|
399
418
|
export {
|
|
400
419
|
MoneyOS,
|
|
420
|
+
NATIVE_TOKEN_ADDRESS,
|
|
401
421
|
OdosProvider,
|
|
402
422
|
chains,
|
|
403
423
|
defaultChain,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/client.ts","../src/core/chains.ts","../src/core/tokens.ts","../src/providers/odos.ts"],"sourcesContent":["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 { 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 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":"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","names":["raw","value","hash","account"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/client.ts","../src/core/chains.ts","../src/core/tokens.ts","../src/providers/odos.ts"],"sourcesContent":["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, NATIVE_TOKEN_ADDRESS } 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 isNativeIn = tokenInAddress === NATIVE_TOKEN_ADDRESS;\n\n if (!isNativeIn) {\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\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: isNativeIn ? amountWei : 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 { 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 NATIVE_TOKEN_ADDRESS =\n \"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\" as Address;\n\nexport const tokens: Record<string, Token> = {\n ETH: {\n symbol: \"ETH\",\n name: \"Ether\",\n decimals: 18,\n addresses: {\n 42161: NATIVE_TOKEN_ADDRESS,\n 1: NATIVE_TOKEN_ADDRESS,\n 137: NATIVE_TOKEN_ADDRESS,\n },\n },\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 type { Address, Hex } from \"viem\";\nimport type { SwapProvider, SwapQuote } from \"../core/types.js\";\nimport { NATIVE_TOKEN_ADDRESS } from \"../core/tokens.js\";\n\nconst ODOS_API = \"https://api.odos.xyz\";\nconst ODOS_NATIVE_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\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 private toOdosAddress(address: Address): Address {\n return address === NATIVE_TOKEN_ADDRESS ? ODOS_NATIVE_ADDRESS : address;\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; sender: Address }> {\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: this.toOdosAddress(params.tokenIn),\n amount: params.amount.toString(),\n },\n ],\n outputTokens: [\n {\n tokenAddress: this.toOdosAddress(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 sender: params.sender,\n };\n }\n\n async getCalldata(\n quote: SwapQuote & { pathId: string; sender: Address },\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.sender,\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":"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","names":["raw","value","hash","account"]}
|