apinow-sdk 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +162 -0
- package/dist/index.js +62 -262
- package/package.json +22 -18
- package/apinow-sdk-0.7.0.tgz +0 -0
- package/index.ts +0 -559
- package/tsconfig.json +0 -15
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# ApiNow SDK
|
|
2
|
+
|
|
3
|
+
A TypeScript SDK for interacting with ApiNow endpoints, supporting Ethereum (including Base), and Solana chains.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Multi-chain support (Ethereum, Base, Solana)
|
|
8
|
+
- Token transfers (ERC20 on ETH/Base, SPL on Solana)
|
|
9
|
+
- Fast mode for quicker transaction processing
|
|
10
|
+
- TypeScript types for better development experience
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install apinow-sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Basic Example
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import apiNow from 'apinow-sdk';
|
|
24
|
+
|
|
25
|
+
// Get endpoint info
|
|
26
|
+
const info = await apiNow.info('https://apinow.fun/api/endpoints/your-endpoint');
|
|
27
|
+
|
|
28
|
+
// Send payment and get response
|
|
29
|
+
const response = await apiNow.infoBuyResponse(
|
|
30
|
+
'https://apinow.fun/api/endpoints/your-endpoint',
|
|
31
|
+
'YOUR_PRIVATE_KEY',
|
|
32
|
+
'YOUR_RPC_URL'
|
|
33
|
+
);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Fast Mode
|
|
37
|
+
|
|
38
|
+
Fast mode skips transaction confirmation and only waits for the transaction to be in the mempool. This provides much faster responses but slightly less security:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
const response = await apiNow.infoBuyResponse(
|
|
42
|
+
'https://apinow.fun/api/endpoints/your-endpoint',
|
|
43
|
+
'YOUR_PRIVATE_KEY',
|
|
44
|
+
'YOUR_RPC_URL',
|
|
45
|
+
{ fastMode: true }
|
|
46
|
+
);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Chain-Specific Examples
|
|
50
|
+
|
|
51
|
+
#### Ethereum/Base
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// Native ETH/BASE transfer
|
|
55
|
+
const txHash = await apiNow.buy(
|
|
56
|
+
'RECIPIENT_ADDRESS',
|
|
57
|
+
ethers.parseEther('0.1'),
|
|
58
|
+
'YOUR_PRIVATE_KEY',
|
|
59
|
+
'YOUR_RPC_URL',
|
|
60
|
+
'eth'
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// ERC20 token transfer
|
|
64
|
+
const txHash = await apiNow.buy(
|
|
65
|
+
'RECIPIENT_ADDRESS',
|
|
66
|
+
ethers.parseUnits('100', 18), // Use appropriate decimals
|
|
67
|
+
'YOUR_PRIVATE_KEY',
|
|
68
|
+
'YOUR_RPC_URL',
|
|
69
|
+
'eth',
|
|
70
|
+
'TOKEN_ADDRESS'
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Solana
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// Native SOL transfer
|
|
78
|
+
const txHash = await apiNow.buy(
|
|
79
|
+
'RECIPIENT_ADDRESS',
|
|
80
|
+
BigInt(LAMPORTS_PER_SOL), // 1 SOL
|
|
81
|
+
'YOUR_PRIVATE_KEY',
|
|
82
|
+
'YOUR_RPC_URL',
|
|
83
|
+
'sol'
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// SPL token transfer
|
|
87
|
+
const txHash = await apiNow.buy(
|
|
88
|
+
'RECIPIENT_ADDRESS',
|
|
89
|
+
BigInt(1000000), // Amount in raw units (e.g. 1.0 for 6 decimals)
|
|
90
|
+
'YOUR_PRIVATE_KEY',
|
|
91
|
+
'YOUR_RPC_URL',
|
|
92
|
+
'sol',
|
|
93
|
+
'TOKEN_ADDRESS'
|
|
94
|
+
);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## API Reference
|
|
98
|
+
|
|
99
|
+
### `info(endpoint: string): Promise<InfoResponse>`
|
|
100
|
+
|
|
101
|
+
Gets information about an endpoint.
|
|
102
|
+
|
|
103
|
+
### `buy(walletAddress: string, amount: bigint, pkey: string, rpc: string, chain?: 'eth' | 'sol', tokenAddress?: string, fastMode?: boolean): Promise<string>`
|
|
104
|
+
|
|
105
|
+
Sends a payment transaction. For tokens, provide the amount in raw units (e.g. wei for ERC20, raw units for SPL).
|
|
106
|
+
|
|
107
|
+
### `txResponse(endpoint: string, txHash: string, opts?: TxResponseOptions): Promise<any>`
|
|
108
|
+
|
|
109
|
+
Gets the API response for a transaction.
|
|
110
|
+
|
|
111
|
+
### `infoBuyResponse(endpoint: string, pkey: string, rpc: string, opts?: TxResponseOptions & { fastMode?: boolean }): Promise<any>`
|
|
112
|
+
|
|
113
|
+
Combines info, buy, and txResponse into a single call.
|
|
114
|
+
|
|
115
|
+
## Types
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
interface TxResponseOptions {
|
|
119
|
+
method?: string;
|
|
120
|
+
data?: any;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
interface InfoResponse {
|
|
124
|
+
requiredAmount: string;
|
|
125
|
+
walletAddress: string;
|
|
126
|
+
httpMethod: string;
|
|
127
|
+
tokenAddress?: string;
|
|
128
|
+
chain: 'eth' | 'sol';
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Error Handling
|
|
133
|
+
|
|
134
|
+
The SDK throws descriptive errors for various failure cases:
|
|
135
|
+
- Invalid endpoint URLs
|
|
136
|
+
- Transaction failures
|
|
137
|
+
- Network issues
|
|
138
|
+
- Invalid addresses or amounts
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT
|
|
143
|
+
|
|
144
|
+
Copyright (c) 2024 Your Name
|
|
145
|
+
|
|
146
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
147
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
148
|
+
in the Software without restriction, including without limitation the rights
|
|
149
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
150
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
151
|
+
furnished to do so, subject to the following conditions:
|
|
152
|
+
|
|
153
|
+
The above copyright notice and permission notice shall be included in all
|
|
154
|
+
copies or substantial portions of the Software.
|
|
155
|
+
|
|
156
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
157
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
158
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
159
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
160
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
161
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
162
|
+
SOFTWARE.
|
package/dist/index.js
CHANGED
|
@@ -1,111 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
const ethers_1 = require("ethers");
|
|
7
|
-
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
|
-
const web3_js_1 = require("@solana/web3.js");
|
|
9
|
-
const spl_token_1 = require("@solana/spl-token");
|
|
10
|
-
const bs58_1 = __importDefault(require("bs58"));
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import fetch from 'node-fetch';
|
|
3
|
+
import { Connection, PublicKey, LAMPORTS_PER_SOL, Transaction, SystemProgram, Keypair, ComputeBudgetProgram } from '@solana/web3.js';
|
|
4
|
+
import { createTransferInstruction, getAssociatedTokenAddress, getMint } from '@solana/spl-token';
|
|
5
|
+
import bs58 from 'bs58';
|
|
11
6
|
class EthereumHandler {
|
|
12
7
|
async buy(walletAddress, amount, pkey, rpc, tokenAddress, fastMode) {
|
|
13
|
-
console.log(`[EthereumHandler] Initiating transaction`);
|
|
14
|
-
console.log(`[EthereumHandler] Transaction details:`, {
|
|
15
|
-
recipient: walletAddress,
|
|
16
|
-
amount: amount.toString(),
|
|
17
|
-
rpc: rpc.substring(0, 20) + '...',
|
|
18
|
-
hasTokenAddress: !!tokenAddress,
|
|
19
|
-
fastMode
|
|
20
|
-
});
|
|
21
8
|
if (!rpc || typeof rpc !== 'string') {
|
|
22
|
-
console.error(`[EthereumHandler] Invalid RPC URL: ${rpc}`);
|
|
23
9
|
throw new Error('Invalid RPC URL');
|
|
24
10
|
}
|
|
25
|
-
if (!walletAddress || !
|
|
26
|
-
console.error(`[EthereumHandler] Invalid wallet address: ${walletAddress}`);
|
|
11
|
+
if (!walletAddress || !ethers.isAddress(walletAddress)) {
|
|
27
12
|
throw new Error('Invalid wallet address');
|
|
28
13
|
}
|
|
14
|
+
const provider = new ethers.JsonRpcProvider(rpc);
|
|
15
|
+
const wallet = new ethers.Wallet(pkey, provider);
|
|
29
16
|
try {
|
|
30
|
-
|
|
31
|
-
const provider = new ethers_1.ethers.JsonRpcProvider(rpc);
|
|
32
|
-
console.log(`[EthereumHandler] Creating wallet from private key`);
|
|
33
|
-
const wallet = new ethers_1.ethers.Wallet(pkey, provider);
|
|
34
|
-
console.log(`[EthereumHandler] Wallet address: ${wallet.address}`);
|
|
35
|
-
console.time(`[EthereumHandler] Get network`);
|
|
36
|
-
const network = await provider.getNetwork();
|
|
37
|
-
console.timeEnd(`[EthereumHandler] Get network`);
|
|
38
|
-
console.log(`[EthereumHandler] Connected to network: ${network.name} (${network.chainId})`);
|
|
39
|
-
console.time(`[EthereumHandler] Get balance`);
|
|
17
|
+
await provider.getNetwork();
|
|
40
18
|
const balance = await provider.getBalance(wallet.address);
|
|
41
|
-
console.
|
|
42
|
-
console.log(`[EthereumHandler] Sender balance: ${ethers_1.ethers.formatEther(balance)} ETH`);
|
|
43
|
-
if (balance < amount && !tokenAddress) {
|
|
44
|
-
console.error(`[EthereumHandler] Insufficient balance: ${ethers_1.ethers.formatEther(balance)} ETH, required: ${ethers_1.ethers.formatEther(amount)} ETH`);
|
|
45
|
-
throw new Error(`Insufficient balance: ${ethers_1.ethers.formatEther(balance)} ETH, required: ${ethers_1.ethers.formatEther(amount)} ETH`);
|
|
46
|
-
}
|
|
47
|
-
console.time(`[EthereumHandler] Get nonce`);
|
|
19
|
+
console.log('Sender balance:', ethers.formatEther(balance), 'ETH');
|
|
48
20
|
const nonce = await provider.getTransactionCount(wallet.address, 'latest');
|
|
49
|
-
console.timeEnd(`[EthereumHandler] Get nonce`);
|
|
50
|
-
console.log(`[EthereumHandler] Nonce: ${nonce}`);
|
|
51
21
|
const gasLimit = wallet.address.toLowerCase() === walletAddress.toLowerCase()
|
|
52
22
|
? 30000
|
|
53
23
|
: 21000;
|
|
54
|
-
console.log(`[EthereumHandler] Gas limit: ${gasLimit}`);
|
|
55
|
-
let txHash;
|
|
56
24
|
if (tokenAddress) {
|
|
57
|
-
console.log(`[EthereumHandler] Executing ERC-20 token transfer`);
|
|
58
|
-
console.log(`[EthereumHandler] Token address: ${tokenAddress}`);
|
|
59
25
|
const abi = ["function transfer(address to, uint256 amount) returns (bool)"];
|
|
60
|
-
|
|
61
|
-
const tokenContract = new ethers_1.ethers.Contract(tokenAddress, abi, wallet);
|
|
62
|
-
console.time(`[EthereumHandler] Token transfer`);
|
|
63
|
-
console.log(`[EthereumHandler] Transferring ${amount.toString()} tokens to ${walletAddress}`);
|
|
26
|
+
const tokenContract = new ethers.Contract(tokenAddress, abi, wallet);
|
|
64
27
|
const tx = await tokenContract.transfer(walletAddress, amount);
|
|
65
|
-
|
|
66
|
-
console.log(`[EthereumHandler] Token transfer transaction hash: ${tx.hash}`);
|
|
67
|
-
txHash = tx.hash;
|
|
28
|
+
return tx.hash;
|
|
68
29
|
}
|
|
69
30
|
else {
|
|
70
|
-
console.log(`[EthereumHandler] Executing native token transfer`);
|
|
71
|
-
console.time(`[EthereumHandler] Native transfer`);
|
|
72
|
-
console.log(`[EthereumHandler] Transferring ${ethers_1.ethers.formatEther(amount)} ETH to ${walletAddress}`);
|
|
73
31
|
const tx = await wallet.sendTransaction({
|
|
74
32
|
to: walletAddress,
|
|
75
33
|
value: amount,
|
|
76
34
|
type: 2,
|
|
77
|
-
maxFeePerGas:
|
|
78
|
-
maxPriorityFeePerGas:
|
|
35
|
+
maxFeePerGas: ethers.parseUnits('0.1', 'gwei'),
|
|
36
|
+
maxPriorityFeePerGas: ethers.parseUnits('0.1', 'gwei'),
|
|
79
37
|
gasLimit,
|
|
80
38
|
nonce
|
|
81
39
|
});
|
|
82
|
-
|
|
83
|
-
console.log(`[EthereumHandler] Native transfer transaction hash: ${tx.hash}`);
|
|
84
|
-
txHash = tx.hash;
|
|
85
|
-
}
|
|
86
|
-
if (!fastMode) {
|
|
87
|
-
console.log(`[EthereumHandler] Waiting for transaction confirmation...`);
|
|
88
|
-
console.time(`[EthereumHandler] Transaction confirmation`);
|
|
89
|
-
const receipt = await provider.waitForTransaction(txHash);
|
|
90
|
-
console.timeEnd(`[EthereumHandler] Transaction confirmation`);
|
|
91
|
-
console.log(`[EthereumHandler] Transaction confirmed:`, {
|
|
92
|
-
blockNumber: receipt?.blockNumber,
|
|
93
|
-
status: receipt?.status === 1 ? 'success' : 'failed',
|
|
94
|
-
gasUsed: receipt?.gasUsed?.toString()
|
|
95
|
-
});
|
|
96
|
-
if (receipt?.status !== 1) {
|
|
97
|
-
console.error(`[EthereumHandler] Transaction failed with status: ${receipt?.status}`);
|
|
98
|
-
throw new Error('Transaction failed');
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
console.log(`[EthereumHandler] Fast mode enabled, not waiting for confirmation`);
|
|
40
|
+
return tx.hash;
|
|
103
41
|
}
|
|
104
|
-
return txHash;
|
|
105
42
|
}
|
|
106
43
|
catch (error) {
|
|
107
|
-
console.error(
|
|
108
|
-
console.error(`[EthereumHandler] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
44
|
+
console.error('Detailed error:', error);
|
|
109
45
|
throw new Error(`Transaction failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
110
46
|
}
|
|
111
47
|
}
|
|
@@ -115,47 +51,40 @@ class SolanaHandler {
|
|
|
115
51
|
let lastError;
|
|
116
52
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
117
53
|
try {
|
|
118
|
-
console.log(
|
|
119
|
-
console.time(`[SolanaHandler] Get blockhash`);
|
|
54
|
+
console.log(`\nAttempt ${attempt}/${maxAttempts}`);
|
|
120
55
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('processed');
|
|
121
|
-
console.
|
|
122
|
-
console.log(`[SolanaHandler] Got blockhash: ${blockhash.slice(0, 10)}...`);
|
|
56
|
+
console.log('Got blockhash:', blockhash.slice(0, 10) + '...');
|
|
123
57
|
transaction.recentBlockhash = blockhash;
|
|
124
58
|
transaction.lastValidBlockHeight = lastValidBlockHeight;
|
|
125
59
|
transaction.feePayer = senderKeypair.publicKey;
|
|
126
60
|
transaction.signatures = [];
|
|
127
61
|
transaction.sign(senderKeypair);
|
|
128
62
|
const rawTx = transaction.serialize();
|
|
129
|
-
console.log(`[SolanaHandler] Transaction serialized, size: ${rawTx.length} bytes`);
|
|
130
|
-
console.time(`[SolanaHandler] Send transaction`);
|
|
131
63
|
const signature = await connection.sendRawTransaction(rawTx, {
|
|
132
64
|
skipPreflight: false,
|
|
133
65
|
maxRetries: 1,
|
|
134
66
|
preflightCommitment: 'processed'
|
|
135
67
|
});
|
|
136
|
-
console.
|
|
137
|
-
console.log(`[SolanaHandler] Transaction sent! Signature: ${signature}`);
|
|
68
|
+
console.log('Transaction sent! Signature:', signature);
|
|
138
69
|
if (!fastMode) {
|
|
139
|
-
console.log(
|
|
70
|
+
console.log('Waiting for confirmation...');
|
|
140
71
|
let confirmationAttempt = 1;
|
|
141
72
|
while (confirmationAttempt <= 5) {
|
|
142
73
|
try {
|
|
143
|
-
console.log(`
|
|
144
|
-
console.time(`[SolanaHandler] Confirm transaction attempt ${confirmationAttempt}`);
|
|
74
|
+
console.log(`Confirmation attempt ${confirmationAttempt}/5`);
|
|
145
75
|
await connection.confirmTransaction({
|
|
146
76
|
signature,
|
|
147
77
|
blockhash,
|
|
148
78
|
lastValidBlockHeight
|
|
149
79
|
}, 'processed');
|
|
150
|
-
console.
|
|
151
|
-
console.log(`[SolanaHandler] Transaction confirmed!`);
|
|
80
|
+
console.log('Transaction confirmed!');
|
|
152
81
|
return signature;
|
|
153
82
|
}
|
|
154
83
|
catch (confirmError) {
|
|
155
84
|
const errorMessage = confirmError instanceof Error
|
|
156
85
|
? confirmError.message
|
|
157
86
|
: 'Unknown confirmation error';
|
|
158
|
-
console.log(
|
|
87
|
+
console.log('Confirmation failed:', errorMessage);
|
|
159
88
|
if (confirmationAttempt === 5)
|
|
160
89
|
throw confirmError;
|
|
161
90
|
confirmationAttempt++;
|
|
@@ -169,11 +98,10 @@ class SolanaHandler {
|
|
|
169
98
|
const errorMessage = error instanceof Error
|
|
170
99
|
? error.message
|
|
171
100
|
: 'Unknown error';
|
|
172
|
-
console.log(
|
|
173
|
-
console.error(`[SolanaHandler] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
101
|
+
console.log('Attempt failed:', errorMessage);
|
|
174
102
|
lastError = error;
|
|
175
103
|
if (attempt < maxAttempts) {
|
|
176
|
-
console.log(
|
|
104
|
+
console.log('Waiting 500ms before retry...');
|
|
177
105
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
178
106
|
}
|
|
179
107
|
}
|
|
@@ -181,71 +109,42 @@ class SolanaHandler {
|
|
|
181
109
|
throw lastError;
|
|
182
110
|
}
|
|
183
111
|
async buy(walletAddress, amount, pkey, rpc, tokenAddress, fastMode) {
|
|
184
|
-
|
|
185
|
-
console.log(`[SolanaHandler] Transaction details:`, {
|
|
186
|
-
recipient: walletAddress,
|
|
187
|
-
amount: amount.toString(),
|
|
188
|
-
rpc: rpc.substring(0, 20) + '...',
|
|
189
|
-
hasTokenAddress: !!tokenAddress,
|
|
190
|
-
fastMode
|
|
191
|
-
});
|
|
192
|
-
console.log(`[SolanaHandler] Creating connection to RPC: ${rpc.substring(0, 20)}...`);
|
|
193
|
-
const connection = new web3_js_1.Connection(rpc, {
|
|
112
|
+
const connection = new Connection(rpc, {
|
|
194
113
|
commitment: 'processed',
|
|
195
114
|
confirmTransactionInitialTimeout: 10000
|
|
196
115
|
});
|
|
197
116
|
try {
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
const senderKeypair = web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(pkey));
|
|
202
|
-
console.log(`[SolanaHandler] Sender public key: ${senderKeypair.publicKey.toString()}`);
|
|
203
|
-
console.log(`[SolanaHandler] Creating transaction`);
|
|
204
|
-
const transaction = new web3_js_1.Transaction();
|
|
117
|
+
const recipientPubkey = new PublicKey(walletAddress);
|
|
118
|
+
const senderKeypair = Keypair.fromSecretKey(bs58.decode(pkey));
|
|
119
|
+
const transaction = new Transaction();
|
|
205
120
|
// Add priority fee instruction
|
|
206
|
-
|
|
207
|
-
transaction.add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
|
|
121
|
+
transaction.add(ComputeBudgetProgram.setComputeUnitPrice({
|
|
208
122
|
microLamports: 50000
|
|
209
123
|
}));
|
|
210
124
|
if (tokenAddress) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
console.time(`[SolanaHandler] Get sender ATA`);
|
|
215
|
-
const senderATA = await (0, spl_token_1.getAssociatedTokenAddress)(mint, senderKeypair.publicKey);
|
|
216
|
-
console.timeEnd(`[SolanaHandler] Get sender ATA`);
|
|
217
|
-
console.log(`[SolanaHandler] Sender ATA: ${senderATA.toString()}`);
|
|
218
|
-
console.time(`[SolanaHandler] Get recipient ATA`);
|
|
219
|
-
const recipientATA = await (0, spl_token_1.getAssociatedTokenAddress)(mint, recipientPubkey);
|
|
220
|
-
console.timeEnd(`[SolanaHandler] Get recipient ATA`);
|
|
221
|
-
console.log(`[SolanaHandler] Recipient ATA: ${recipientATA.toString()}`);
|
|
125
|
+
const mint = new PublicKey(tokenAddress);
|
|
126
|
+
const senderATA = await getAssociatedTokenAddress(mint, senderKeypair.publicKey);
|
|
127
|
+
const recipientATA = await getAssociatedTokenAddress(mint, recipientPubkey);
|
|
222
128
|
// Get token decimals
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
console.
|
|
226
|
-
console.log(`[SolanaHandler] Token decimals: ${mintInfo.decimals}`);
|
|
227
|
-
console.log(`[SolanaHandler] Original amount: ${amount.toString()}`);
|
|
129
|
+
const mintInfo = await getMint(connection, mint);
|
|
130
|
+
console.log('Token decimals:', mintInfo.decimals);
|
|
131
|
+
console.log('Original amount:', amount.toString());
|
|
228
132
|
// Don't multiply by decimals since amount is already raw
|
|
229
|
-
|
|
230
|
-
transaction.add((0, spl_token_1.createTransferInstruction)(senderATA, recipientATA, senderKeypair.publicKey, Number(amount) // Use raw amount directly
|
|
133
|
+
transaction.add(createTransferInstruction(senderATA, recipientATA, senderKeypair.publicKey, Number(amount) // Use raw amount directly
|
|
231
134
|
));
|
|
232
135
|
}
|
|
233
136
|
else {
|
|
234
137
|
// SOL transfer
|
|
235
|
-
|
|
236
|
-
console.log(`[SolanaHandler] Adding SOL transfer instruction: ${Number(amount)} lamports`);
|
|
237
|
-
transaction.add(web3_js_1.SystemProgram.transfer({
|
|
138
|
+
transaction.add(SystemProgram.transfer({
|
|
238
139
|
fromPubkey: senderKeypair.publicKey,
|
|
239
140
|
toPubkey: recipientPubkey,
|
|
240
141
|
lamports: Number(amount)
|
|
241
142
|
}));
|
|
242
143
|
}
|
|
243
|
-
console.log(`[SolanaHandler] Sending transaction with retry logic`);
|
|
244
144
|
return await this.sendWithRetry(connection, transaction, senderKeypair, !!fastMode);
|
|
245
145
|
}
|
|
246
146
|
catch (error) {
|
|
247
|
-
console.error(
|
|
248
|
-
console.error(`[SolanaHandler] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
147
|
+
console.error('Detailed error:', error);
|
|
249
148
|
throw new Error(`Transaction failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
250
149
|
}
|
|
251
150
|
}
|
|
@@ -259,78 +158,28 @@ class ApiNow {
|
|
|
259
158
|
};
|
|
260
159
|
}
|
|
261
160
|
async info(endpoint) {
|
|
262
|
-
console.log(`[ApiNow] Fetching info from endpoint: ${endpoint}`);
|
|
263
161
|
if (!endpoint.startsWith('https://apinow.fun/api/endpoints/')) {
|
|
264
|
-
console.error(`[ApiNow] Invalid endpoint URL format: ${endpoint}`);
|
|
265
162
|
throw new Error('Invalid endpoint URL format');
|
|
266
163
|
}
|
|
267
|
-
console.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
console.log(`[ApiNow] Info response status: ${response.status}`);
|
|
272
|
-
if (!response.ok) {
|
|
273
|
-
console.error(`[ApiNow] Failed to fetch endpoint info: ${response.status} ${response.statusText}`);
|
|
274
|
-
const errorText = await response.text();
|
|
275
|
-
console.error(`[ApiNow] Error response body: ${errorText}`);
|
|
276
|
-
throw new Error(`Failed to fetch endpoint info: ${response.status}`);
|
|
277
|
-
}
|
|
278
|
-
const data = await response.json();
|
|
279
|
-
console.log(`[ApiNow] Endpoint info retrieved:`, {
|
|
280
|
-
chain: data.chain,
|
|
281
|
-
requiredAmount: data.requiredAmount,
|
|
282
|
-
walletAddress: data.walletAddress,
|
|
283
|
-
httpMethod: data.httpMethod,
|
|
284
|
-
hasTokenAddress: !!data.tokenAddress
|
|
285
|
-
});
|
|
286
|
-
return data;
|
|
287
|
-
}
|
|
288
|
-
catch (error) {
|
|
289
|
-
console.error(`[ApiNow] Error fetching endpoint info:`, error);
|
|
290
|
-
console.error(`[ApiNow] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
291
|
-
throw error;
|
|
164
|
+
console.log(`Fetching info from ${endpoint}`);
|
|
165
|
+
const response = await fetch(`${endpoint}`);
|
|
166
|
+
if (!response.ok) {
|
|
167
|
+
throw new Error(`Failed to fetch endpoint info: ${response.status}`);
|
|
292
168
|
}
|
|
169
|
+
return response.json();
|
|
293
170
|
}
|
|
294
171
|
async buy(walletAddress, amount, pkey, rpc, chain = 'eth', tokenAddress, fastMode) {
|
|
295
|
-
console.log(`[ApiNow] Initiating transaction on chain: ${chain}`);
|
|
296
|
-
console.log(`[ApiNow] Transaction details:`, {
|
|
297
|
-
recipient: walletAddress,
|
|
298
|
-
amount: amount.toString(),
|
|
299
|
-
chain,
|
|
300
|
-
hasTokenAddress: !!tokenAddress,
|
|
301
|
-
fastMode
|
|
302
|
-
});
|
|
303
172
|
const handler = this.handlers[chain];
|
|
304
173
|
if (!handler) {
|
|
305
|
-
console.error(`[ApiNow] Unsupported chain: ${chain}`);
|
|
306
174
|
throw new Error(`Unsupported chain: ${chain}`);
|
|
307
175
|
}
|
|
308
|
-
|
|
309
|
-
try {
|
|
310
|
-
const txHash = await handler.buy(walletAddress, amount, pkey, rpc, tokenAddress, fastMode);
|
|
311
|
-
console.timeEnd(`[ApiNow] Transaction on ${chain}`);
|
|
312
|
-
console.log(`[ApiNow] Transaction successful with hash: ${txHash}`);
|
|
313
|
-
return txHash;
|
|
314
|
-
}
|
|
315
|
-
catch (error) {
|
|
316
|
-
console.timeEnd(`[ApiNow] Transaction on ${chain}`);
|
|
317
|
-
console.error(`[ApiNow] Transaction failed:`, error);
|
|
318
|
-
console.error(`[ApiNow] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
319
|
-
throw error;
|
|
320
|
-
}
|
|
176
|
+
return handler.buy(walletAddress, amount, pkey, rpc, tokenAddress, fastMode);
|
|
321
177
|
}
|
|
322
178
|
async txResponse(endpoint, txHash, opts = {}) {
|
|
323
|
-
console.log(`[ApiNow] Making API call with transaction hash`);
|
|
324
|
-
console.log(`[ApiNow] Call details:`, {
|
|
325
|
-
endpoint,
|
|
326
|
-
txHash,
|
|
327
|
-
method: opts.method || 'GET',
|
|
328
|
-
hasData: !!opts.data
|
|
329
|
-
});
|
|
330
179
|
if (!endpoint.startsWith('https://apinow.fun/api/endpoints/')) {
|
|
331
|
-
console.error(`[ApiNow] Invalid endpoint URL format: ${endpoint}`);
|
|
332
180
|
throw new Error('Invalid endpoint URL format');
|
|
333
181
|
}
|
|
182
|
+
console.log('txResponse:', { endpoint, txHash, ...opts });
|
|
334
183
|
const options = {
|
|
335
184
|
method: opts.method || 'GET',
|
|
336
185
|
headers: {
|
|
@@ -339,74 +188,25 @@ class ApiNow {
|
|
|
339
188
|
},
|
|
340
189
|
...(opts.data && { body: JSON.stringify(opts.data) })
|
|
341
190
|
};
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
hasBody: !!options.body
|
|
346
|
-
});
|
|
347
|
-
console.time(`[ApiNow] API call with transaction hash`);
|
|
348
|
-
try {
|
|
349
|
-
const response = await (0, node_fetch_1.default)(endpoint, options);
|
|
350
|
-
console.timeEnd(`[ApiNow] API call with transaction hash`);
|
|
351
|
-
console.log(`[ApiNow] Response status: ${response.status}`);
|
|
352
|
-
if (!response.ok) {
|
|
353
|
-
console.error(`[ApiNow] API request failed: ${response.status} ${response.statusText}`);
|
|
354
|
-
const errorText = await response.text();
|
|
355
|
-
console.error(`[ApiNow] Error response body: ${errorText}`);
|
|
356
|
-
throw new Error(`API request failed: ${response.status}`);
|
|
357
|
-
}
|
|
358
|
-
const data = await response.json();
|
|
359
|
-
console.log(`[ApiNow] API call successful with data type: ${typeof data}`);
|
|
360
|
-
return data;
|
|
361
|
-
}
|
|
362
|
-
catch (error) {
|
|
363
|
-
console.timeEnd(`[ApiNow] API call with transaction hash`);
|
|
364
|
-
console.error(`[ApiNow] API call failed:`, error);
|
|
365
|
-
console.error(`[ApiNow] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
366
|
-
throw error;
|
|
191
|
+
const response = await fetch(endpoint, options);
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
throw new Error(`API request failed: ${response.status}`);
|
|
367
194
|
}
|
|
195
|
+
return response.json();
|
|
368
196
|
}
|
|
369
197
|
async infoBuyResponse(endpoint, pkey, rpc, opts = {}) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
198
|
+
const info = await this.info(endpoint);
|
|
199
|
+
const amount = info.chain === 'sol'
|
|
200
|
+
? BigInt(Math.round(Number(info.requiredAmount) * LAMPORTS_PER_SOL))
|
|
201
|
+
: ethers.parseEther(info.requiredAmount);
|
|
202
|
+
const txHash = await this.buy(info.walletAddress, amount, pkey, rpc, info.chain, info.tokenAddress, opts.fastMode);
|
|
203
|
+
console.log('infoBuyResponse:', { endpoint, txHash, ...opts });
|
|
204
|
+
const response = await this.txResponse(endpoint, txHash, {
|
|
205
|
+
method: opts.method || info.httpMethod,
|
|
206
|
+
data: opts.data
|
|
375
207
|
});
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
// Step 1: Get endpoint info
|
|
379
|
-
console.time(`[ApiNow] Get endpoint info`);
|
|
380
|
-
const info = await this.info(endpoint);
|
|
381
|
-
console.timeEnd(`[ApiNow] Get endpoint info`);
|
|
382
|
-
// Step 2: Calculate amount
|
|
383
|
-
console.log(`[ApiNow] Calculating transaction amount for chain: ${info.chain}`);
|
|
384
|
-
const amount = info.chain === 'sol'
|
|
385
|
-
? BigInt(Math.round(Number(info.requiredAmount) * web3_js_1.LAMPORTS_PER_SOL))
|
|
386
|
-
: ethers_1.ethers.parseEther(info.requiredAmount);
|
|
387
|
-
console.log(`[ApiNow] Calculated amount: ${amount.toString()}`);
|
|
388
|
-
// Step 3: Execute transaction
|
|
389
|
-
console.time(`[ApiNow] Execute transaction`);
|
|
390
|
-
const txHash = await this.buy(info.walletAddress, amount, pkey, rpc, info.chain, info.tokenAddress, opts.fastMode);
|
|
391
|
-
console.timeEnd(`[ApiNow] Execute transaction`);
|
|
392
|
-
// Step 4: Make API call with transaction hash
|
|
393
|
-
console.log(`[ApiNow] Making API call with transaction hash: ${txHash}`);
|
|
394
|
-
console.time(`[ApiNow] API call with transaction hash`);
|
|
395
|
-
const response = await this.txResponse(endpoint, txHash, {
|
|
396
|
-
method: opts.method || info.httpMethod,
|
|
397
|
-
data: opts.data
|
|
398
|
-
});
|
|
399
|
-
console.timeEnd(`[ApiNow] API call with transaction hash`);
|
|
400
|
-
console.timeEnd(`[ApiNow] Total infoBuyResponse flow`);
|
|
401
|
-
console.log(`[ApiNow] infoBuyResponse flow completed successfully`);
|
|
402
|
-
return response;
|
|
403
|
-
}
|
|
404
|
-
catch (error) {
|
|
405
|
-
console.timeEnd(`[ApiNow] Total infoBuyResponse flow`);
|
|
406
|
-
console.error(`[ApiNow] infoBuyResponse flow failed:`, error);
|
|
407
|
-
console.error(`[ApiNow] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
408
|
-
throw error;
|
|
409
|
-
}
|
|
208
|
+
console.log('response:', response);
|
|
209
|
+
return response;
|
|
410
210
|
}
|
|
411
211
|
}
|
|
412
|
-
|
|
212
|
+
export default new ApiNow();
|
package/package.json
CHANGED
|
@@ -1,33 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apinow-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "SDK
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "ApiNow SDK · The endpoint vending machine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
7
11
|
"scripts": {
|
|
8
12
|
"build": "tsc",
|
|
9
|
-
"
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"prepare": "npm run build"
|
|
10
15
|
},
|
|
11
16
|
"keywords": [
|
|
12
17
|
"api",
|
|
13
|
-
"apinowfun",
|
|
14
|
-
"apinow",
|
|
15
|
-
"blockchain",
|
|
16
18
|
"ethereum",
|
|
17
|
-
"
|
|
19
|
+
"web3"
|
|
18
20
|
],
|
|
19
|
-
"author": "ApiNow
|
|
21
|
+
"author": "ApiNow.fun",
|
|
20
22
|
"license": "MIT",
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@types/bs58": "^4.0.4",
|
|
23
|
-
"@types/node": "^20.17.24",
|
|
24
|
-
"typescript": "^5.8.2"
|
|
25
|
-
},
|
|
26
23
|
"dependencies": {
|
|
27
|
-
"@solana/spl-token": "^0.
|
|
28
|
-
"@solana/web3.js": "^1.
|
|
29
|
-
"bs58": "^
|
|
30
|
-
"ethers": "^6.
|
|
24
|
+
"@solana/spl-token": "^0.4.12",
|
|
25
|
+
"@solana/web3.js": "^1.98.0",
|
|
26
|
+
"bs58": "^6.0.0",
|
|
27
|
+
"ethers": "^6.13.5",
|
|
31
28
|
"node-fetch": "^3.3.2"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/jest": "^29.5.12",
|
|
32
|
+
"@types/node": "^20.11.24",
|
|
33
|
+
"jest": "^29.7.0",
|
|
34
|
+
"ts-jest": "^29.1.2",
|
|
35
|
+
"typescript": "^5.3.3"
|
|
32
36
|
}
|
|
33
|
-
}
|
|
37
|
+
}
|
package/apinow-sdk-0.7.0.tgz
DELETED
|
Binary file
|
package/index.ts
DELETED
|
@@ -1,559 +0,0 @@
|
|
|
1
|
-
import { ethers } from 'ethers';
|
|
2
|
-
import fetch from 'node-fetch';
|
|
3
|
-
import {
|
|
4
|
-
Connection,
|
|
5
|
-
PublicKey,
|
|
6
|
-
LAMPORTS_PER_SOL,
|
|
7
|
-
Transaction,
|
|
8
|
-
SystemProgram,
|
|
9
|
-
Keypair,
|
|
10
|
-
ComputeBudgetProgram
|
|
11
|
-
} from '@solana/web3.js';
|
|
12
|
-
import {
|
|
13
|
-
createTransferInstruction,
|
|
14
|
-
getAssociatedTokenAddress,
|
|
15
|
-
TOKEN_PROGRAM_ID,
|
|
16
|
-
getMint
|
|
17
|
-
} from '@solana/spl-token';
|
|
18
|
-
import bs58 from 'bs58';
|
|
19
|
-
|
|
20
|
-
interface TxResponseOptions {
|
|
21
|
-
method?: string;
|
|
22
|
-
data?: any;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface InfoResponse {
|
|
26
|
-
requiredAmount: string;
|
|
27
|
-
walletAddress: string;
|
|
28
|
-
httpMethod: string;
|
|
29
|
-
tokenAddress?: string;
|
|
30
|
-
chain: 'eth' | 'sol' | 'base';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface ChainHandler {
|
|
34
|
-
buy(
|
|
35
|
-
walletAddress: string,
|
|
36
|
-
amount: bigint,
|
|
37
|
-
pkey: string,
|
|
38
|
-
rpc: string,
|
|
39
|
-
tokenAddress?: string,
|
|
40
|
-
fastMode?: boolean
|
|
41
|
-
): Promise<string>;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
class EthereumHandler implements ChainHandler {
|
|
45
|
-
async buy(
|
|
46
|
-
walletAddress: string,
|
|
47
|
-
amount: bigint,
|
|
48
|
-
pkey: string,
|
|
49
|
-
rpc: string,
|
|
50
|
-
tokenAddress?: string,
|
|
51
|
-
fastMode?: boolean
|
|
52
|
-
): Promise<string> {
|
|
53
|
-
console.log(`[EthereumHandler] Initiating transaction`);
|
|
54
|
-
console.log(`[EthereumHandler] Transaction details:`, {
|
|
55
|
-
recipient: walletAddress,
|
|
56
|
-
amount: amount.toString(),
|
|
57
|
-
rpc: rpc.substring(0, 20) + '...',
|
|
58
|
-
hasTokenAddress: !!tokenAddress,
|
|
59
|
-
fastMode
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
if (!rpc || typeof rpc !== 'string') {
|
|
63
|
-
console.error(`[EthereumHandler] Invalid RPC URL: ${rpc}`);
|
|
64
|
-
throw new Error('Invalid RPC URL');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (!walletAddress || !ethers.isAddress(walletAddress)) {
|
|
68
|
-
console.error(`[EthereumHandler] Invalid wallet address: ${walletAddress}`);
|
|
69
|
-
throw new Error('Invalid wallet address');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
console.log(`[EthereumHandler] Creating provider with RPC: ${rpc.substring(0, 20)}...`);
|
|
74
|
-
const provider = new ethers.JsonRpcProvider(rpc);
|
|
75
|
-
|
|
76
|
-
console.log(`[EthereumHandler] Creating wallet from private key`);
|
|
77
|
-
const wallet = new ethers.Wallet(pkey, provider);
|
|
78
|
-
console.log(`[EthereumHandler] Wallet address: ${wallet.address}`);
|
|
79
|
-
|
|
80
|
-
console.time(`[EthereumHandler] Get network`);
|
|
81
|
-
const network = await provider.getNetwork();
|
|
82
|
-
console.timeEnd(`[EthereumHandler] Get network`);
|
|
83
|
-
console.log(`[EthereumHandler] Connected to network: ${network.name} (${network.chainId})`);
|
|
84
|
-
|
|
85
|
-
console.time(`[EthereumHandler] Get balance`);
|
|
86
|
-
const balance = await provider.getBalance(wallet.address);
|
|
87
|
-
console.timeEnd(`[EthereumHandler] Get balance`);
|
|
88
|
-
console.log(`[EthereumHandler] Sender balance: ${ethers.formatEther(balance)} ETH`);
|
|
89
|
-
|
|
90
|
-
if (balance < amount && !tokenAddress) {
|
|
91
|
-
console.error(`[EthereumHandler] Insufficient balance: ${ethers.formatEther(balance)} ETH, required: ${ethers.formatEther(amount)} ETH`);
|
|
92
|
-
throw new Error(`Insufficient balance: ${ethers.formatEther(balance)} ETH, required: ${ethers.formatEther(amount)} ETH`);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
console.time(`[EthereumHandler] Get nonce`);
|
|
96
|
-
const nonce = await provider.getTransactionCount(wallet.address, 'latest');
|
|
97
|
-
console.timeEnd(`[EthereumHandler] Get nonce`);
|
|
98
|
-
console.log(`[EthereumHandler] Nonce: ${nonce}`);
|
|
99
|
-
|
|
100
|
-
const gasLimit = wallet.address.toLowerCase() === walletAddress.toLowerCase()
|
|
101
|
-
? 30000
|
|
102
|
-
: 21000;
|
|
103
|
-
console.log(`[EthereumHandler] Gas limit: ${gasLimit}`);
|
|
104
|
-
|
|
105
|
-
let txHash: string;
|
|
106
|
-
|
|
107
|
-
if (tokenAddress) {
|
|
108
|
-
console.log(`[EthereumHandler] Executing ERC-20 token transfer`);
|
|
109
|
-
console.log(`[EthereumHandler] Token address: ${tokenAddress}`);
|
|
110
|
-
|
|
111
|
-
const abi = ["function transfer(address to, uint256 amount) returns (bool)"];
|
|
112
|
-
console.log(`[EthereumHandler] Creating token contract instance`);
|
|
113
|
-
const tokenContract = new ethers.Contract(tokenAddress, abi, wallet);
|
|
114
|
-
|
|
115
|
-
console.time(`[EthereumHandler] Token transfer`);
|
|
116
|
-
console.log(`[EthereumHandler] Transferring ${amount.toString()} tokens to ${walletAddress}`);
|
|
117
|
-
const tx = await tokenContract.transfer(walletAddress, amount);
|
|
118
|
-
console.timeEnd(`[EthereumHandler] Token transfer`);
|
|
119
|
-
|
|
120
|
-
console.log(`[EthereumHandler] Token transfer transaction hash: ${tx.hash}`);
|
|
121
|
-
txHash = tx.hash;
|
|
122
|
-
} else {
|
|
123
|
-
console.log(`[EthereumHandler] Executing native token transfer`);
|
|
124
|
-
|
|
125
|
-
console.time(`[EthereumHandler] Native transfer`);
|
|
126
|
-
console.log(`[EthereumHandler] Transferring ${ethers.formatEther(amount)} ETH to ${walletAddress}`);
|
|
127
|
-
const tx = await wallet.sendTransaction({
|
|
128
|
-
to: walletAddress,
|
|
129
|
-
value: amount,
|
|
130
|
-
type: 2,
|
|
131
|
-
maxFeePerGas: ethers.parseUnits('0.1', 'gwei'),
|
|
132
|
-
maxPriorityFeePerGas: ethers.parseUnits('0.1', 'gwei'),
|
|
133
|
-
gasLimit,
|
|
134
|
-
nonce
|
|
135
|
-
});
|
|
136
|
-
console.timeEnd(`[EthereumHandler] Native transfer`);
|
|
137
|
-
|
|
138
|
-
console.log(`[EthereumHandler] Native transfer transaction hash: ${tx.hash}`);
|
|
139
|
-
txHash = tx.hash;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!fastMode) {
|
|
143
|
-
console.log(`[EthereumHandler] Waiting for transaction confirmation...`);
|
|
144
|
-
console.time(`[EthereumHandler] Transaction confirmation`);
|
|
145
|
-
const receipt = await provider.waitForTransaction(txHash);
|
|
146
|
-
console.timeEnd(`[EthereumHandler] Transaction confirmation`);
|
|
147
|
-
|
|
148
|
-
console.log(`[EthereumHandler] Transaction confirmed:`, {
|
|
149
|
-
blockNumber: receipt?.blockNumber,
|
|
150
|
-
status: receipt?.status === 1 ? 'success' : 'failed',
|
|
151
|
-
gasUsed: receipt?.gasUsed?.toString()
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
if (receipt?.status !== 1) {
|
|
155
|
-
console.error(`[EthereumHandler] Transaction failed with status: ${receipt?.status}`);
|
|
156
|
-
throw new Error('Transaction failed');
|
|
157
|
-
}
|
|
158
|
-
} else {
|
|
159
|
-
console.log(`[EthereumHandler] Fast mode enabled, not waiting for confirmation`);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return txHash;
|
|
163
|
-
} catch (error: unknown) {
|
|
164
|
-
console.error(`[EthereumHandler] Transaction failed:`, error);
|
|
165
|
-
console.error(`[EthereumHandler] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
166
|
-
throw new Error(
|
|
167
|
-
`Transaction failed: ${error instanceof Error ? error.message : String(error)}`
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
class SolanaHandler implements ChainHandler {
|
|
174
|
-
private async sendWithRetry(
|
|
175
|
-
connection: Connection,
|
|
176
|
-
transaction: Transaction,
|
|
177
|
-
senderKeypair: Keypair,
|
|
178
|
-
fastMode: boolean,
|
|
179
|
-
maxAttempts = 3
|
|
180
|
-
): Promise<string> {
|
|
181
|
-
let lastError;
|
|
182
|
-
|
|
183
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
184
|
-
try {
|
|
185
|
-
console.log(`[SolanaHandler] Attempt ${attempt}/${maxAttempts}`);
|
|
186
|
-
|
|
187
|
-
console.time(`[SolanaHandler] Get blockhash`);
|
|
188
|
-
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('processed');
|
|
189
|
-
console.timeEnd(`[SolanaHandler] Get blockhash`);
|
|
190
|
-
console.log(`[SolanaHandler] Got blockhash: ${blockhash.slice(0, 10)}...`);
|
|
191
|
-
|
|
192
|
-
transaction.recentBlockhash = blockhash;
|
|
193
|
-
transaction.lastValidBlockHeight = lastValidBlockHeight;
|
|
194
|
-
transaction.feePayer = senderKeypair.publicKey;
|
|
195
|
-
|
|
196
|
-
transaction.signatures = [];
|
|
197
|
-
transaction.sign(senderKeypair);
|
|
198
|
-
|
|
199
|
-
const rawTx = transaction.serialize();
|
|
200
|
-
console.log(`[SolanaHandler] Transaction serialized, size: ${rawTx.length} bytes`);
|
|
201
|
-
|
|
202
|
-
console.time(`[SolanaHandler] Send transaction`);
|
|
203
|
-
const signature = await connection.sendRawTransaction(rawTx, {
|
|
204
|
-
skipPreflight: false,
|
|
205
|
-
maxRetries: 1,
|
|
206
|
-
preflightCommitment: 'processed'
|
|
207
|
-
});
|
|
208
|
-
console.timeEnd(`[SolanaHandler] Send transaction`);
|
|
209
|
-
console.log(`[SolanaHandler] Transaction sent! Signature: ${signature}`);
|
|
210
|
-
|
|
211
|
-
if (!fastMode) {
|
|
212
|
-
console.log(`[SolanaHandler] Waiting for confirmation...`);
|
|
213
|
-
let confirmationAttempt = 1;
|
|
214
|
-
while (confirmationAttempt <= 5) {
|
|
215
|
-
try {
|
|
216
|
-
console.log(`[SolanaHandler] Confirmation attempt ${confirmationAttempt}/5`);
|
|
217
|
-
console.time(`[SolanaHandler] Confirm transaction attempt ${confirmationAttempt}`);
|
|
218
|
-
await connection.confirmTransaction({
|
|
219
|
-
signature,
|
|
220
|
-
blockhash,
|
|
221
|
-
lastValidBlockHeight
|
|
222
|
-
}, 'processed');
|
|
223
|
-
console.timeEnd(`[SolanaHandler] Confirm transaction attempt ${confirmationAttempt}`);
|
|
224
|
-
console.log(`[SolanaHandler] Transaction confirmed!`);
|
|
225
|
-
return signature;
|
|
226
|
-
} catch (confirmError: unknown) {
|
|
227
|
-
const errorMessage = confirmError instanceof Error
|
|
228
|
-
? confirmError.message
|
|
229
|
-
: 'Unknown confirmation error';
|
|
230
|
-
console.log(`[SolanaHandler] Confirmation failed: ${errorMessage}`);
|
|
231
|
-
if (confirmationAttempt === 5) throw confirmError;
|
|
232
|
-
confirmationAttempt++;
|
|
233
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return signature;
|
|
239
|
-
} catch (error: unknown) {
|
|
240
|
-
const errorMessage = error instanceof Error
|
|
241
|
-
? error.message
|
|
242
|
-
: 'Unknown error';
|
|
243
|
-
console.log(`[SolanaHandler] Attempt failed: ${errorMessage}`);
|
|
244
|
-
console.error(`[SolanaHandler] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
245
|
-
lastError = error;
|
|
246
|
-
if (attempt < maxAttempts) {
|
|
247
|
-
console.log(`[SolanaHandler] Waiting 500ms before retry...`);
|
|
248
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
throw lastError;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
async buy(
|
|
256
|
-
walletAddress: string,
|
|
257
|
-
amount: bigint,
|
|
258
|
-
pkey: string,
|
|
259
|
-
rpc: string,
|
|
260
|
-
tokenAddress?: string,
|
|
261
|
-
fastMode?: boolean
|
|
262
|
-
): Promise<string> {
|
|
263
|
-
console.log(`[SolanaHandler] Initiating transaction`);
|
|
264
|
-
console.log(`[SolanaHandler] Transaction details:`, {
|
|
265
|
-
recipient: walletAddress,
|
|
266
|
-
amount: amount.toString(),
|
|
267
|
-
rpc: rpc.substring(0, 20) + '...',
|
|
268
|
-
hasTokenAddress: !!tokenAddress,
|
|
269
|
-
fastMode
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
console.log(`[SolanaHandler] Creating connection to RPC: ${rpc.substring(0, 20)}...`);
|
|
273
|
-
const connection = new Connection(rpc, {
|
|
274
|
-
commitment: 'processed',
|
|
275
|
-
confirmTransactionInitialTimeout: 10000
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
try {
|
|
279
|
-
console.log(`[SolanaHandler] Parsing recipient public key: ${walletAddress}`);
|
|
280
|
-
const recipientPubkey = new PublicKey(walletAddress);
|
|
281
|
-
|
|
282
|
-
console.log(`[SolanaHandler] Creating sender keypair from private key`);
|
|
283
|
-
const senderKeypair = Keypair.fromSecretKey(bs58.decode(pkey));
|
|
284
|
-
console.log(`[SolanaHandler] Sender public key: ${senderKeypair.publicKey.toString()}`);
|
|
285
|
-
|
|
286
|
-
console.log(`[SolanaHandler] Creating transaction`);
|
|
287
|
-
const transaction = new Transaction();
|
|
288
|
-
|
|
289
|
-
// Add priority fee instruction
|
|
290
|
-
console.log(`[SolanaHandler] Adding compute unit price instruction (priority fee)`);
|
|
291
|
-
transaction.add(
|
|
292
|
-
ComputeBudgetProgram.setComputeUnitPrice({
|
|
293
|
-
microLamports: 50000
|
|
294
|
-
})
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
if (tokenAddress) {
|
|
298
|
-
console.log(`[SolanaHandler] Preparing SPL token transfer`);
|
|
299
|
-
console.log(`[SolanaHandler] Token address: ${tokenAddress}`);
|
|
300
|
-
|
|
301
|
-
const mint = new PublicKey(tokenAddress);
|
|
302
|
-
|
|
303
|
-
console.time(`[SolanaHandler] Get sender ATA`);
|
|
304
|
-
const senderATA = await getAssociatedTokenAddress(mint, senderKeypair.publicKey);
|
|
305
|
-
console.timeEnd(`[SolanaHandler] Get sender ATA`);
|
|
306
|
-
console.log(`[SolanaHandler] Sender ATA: ${senderATA.toString()}`);
|
|
307
|
-
|
|
308
|
-
console.time(`[SolanaHandler] Get recipient ATA`);
|
|
309
|
-
const recipientATA = await getAssociatedTokenAddress(mint, recipientPubkey);
|
|
310
|
-
console.timeEnd(`[SolanaHandler] Get recipient ATA`);
|
|
311
|
-
console.log(`[SolanaHandler] Recipient ATA: ${recipientATA.toString()}`);
|
|
312
|
-
|
|
313
|
-
// Get token decimals
|
|
314
|
-
console.time(`[SolanaHandler] Get mint info`);
|
|
315
|
-
const mintInfo = await getMint(connection, mint);
|
|
316
|
-
console.timeEnd(`[SolanaHandler] Get mint info`);
|
|
317
|
-
console.log(`[SolanaHandler] Token decimals: ${mintInfo.decimals}`);
|
|
318
|
-
console.log(`[SolanaHandler] Original amount: ${amount.toString()}`);
|
|
319
|
-
|
|
320
|
-
// Don't multiply by decimals since amount is already raw
|
|
321
|
-
console.log(`[SolanaHandler] Adding token transfer instruction`);
|
|
322
|
-
transaction.add(
|
|
323
|
-
createTransferInstruction(
|
|
324
|
-
senderATA,
|
|
325
|
-
recipientATA,
|
|
326
|
-
senderKeypair.publicKey,
|
|
327
|
-
Number(amount) // Use raw amount directly
|
|
328
|
-
)
|
|
329
|
-
);
|
|
330
|
-
} else {
|
|
331
|
-
// SOL transfer
|
|
332
|
-
console.log(`[SolanaHandler] Preparing SOL transfer`);
|
|
333
|
-
console.log(`[SolanaHandler] Adding SOL transfer instruction: ${Number(amount)} lamports`);
|
|
334
|
-
transaction.add(
|
|
335
|
-
SystemProgram.transfer({
|
|
336
|
-
fromPubkey: senderKeypair.publicKey,
|
|
337
|
-
toPubkey: recipientPubkey,
|
|
338
|
-
lamports: Number(amount)
|
|
339
|
-
})
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
console.log(`[SolanaHandler] Sending transaction with retry logic`);
|
|
344
|
-
return await this.sendWithRetry(connection, transaction, senderKeypair, !!fastMode);
|
|
345
|
-
|
|
346
|
-
} catch (error: unknown) {
|
|
347
|
-
console.error(`[SolanaHandler] Transaction failed:`, error);
|
|
348
|
-
console.error(`[SolanaHandler] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
349
|
-
throw new Error(
|
|
350
|
-
`Transaction failed: ${error instanceof Error ? error.message : String(error)}`
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
class ApiNow {
|
|
357
|
-
private handlers: { [key: string]: ChainHandler } = {
|
|
358
|
-
eth: new EthereumHandler(),
|
|
359
|
-
sol: new SolanaHandler(),
|
|
360
|
-
base: new EthereumHandler()
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
async info(endpoint: string): Promise<InfoResponse> {
|
|
364
|
-
console.log(`[ApiNow] Fetching info from endpoint: ${endpoint}`);
|
|
365
|
-
|
|
366
|
-
if (!endpoint.startsWith('https://apinow.fun/api/endpoints/')) {
|
|
367
|
-
console.error(`[ApiNow] Invalid endpoint URL format: ${endpoint}`);
|
|
368
|
-
throw new Error('Invalid endpoint URL format');
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
console.time(`[ApiNow] Fetch endpoint info`);
|
|
372
|
-
try {
|
|
373
|
-
const response = await fetch(`${endpoint}`);
|
|
374
|
-
console.timeEnd(`[ApiNow] Fetch endpoint info`);
|
|
375
|
-
console.log(`[ApiNow] Info response status: ${response.status}`);
|
|
376
|
-
|
|
377
|
-
if (!response.ok) {
|
|
378
|
-
console.error(`[ApiNow] Failed to fetch endpoint info: ${response.status} ${response.statusText}`);
|
|
379
|
-
const errorText = await response.text();
|
|
380
|
-
console.error(`[ApiNow] Error response body: ${errorText}`);
|
|
381
|
-
throw new Error(`Failed to fetch endpoint info: ${response.status}`);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
const data = await response.json() as InfoResponse;
|
|
385
|
-
console.log(`[ApiNow] Endpoint info retrieved:`, {
|
|
386
|
-
chain: data.chain,
|
|
387
|
-
requiredAmount: data.requiredAmount,
|
|
388
|
-
walletAddress: data.walletAddress,
|
|
389
|
-
httpMethod: data.httpMethod,
|
|
390
|
-
hasTokenAddress: !!data.tokenAddress
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
return data;
|
|
394
|
-
} catch (error) {
|
|
395
|
-
console.error(`[ApiNow] Error fetching endpoint info:`, error);
|
|
396
|
-
console.error(`[ApiNow] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
397
|
-
throw error;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
async buy(
|
|
402
|
-
walletAddress: string,
|
|
403
|
-
amount: bigint,
|
|
404
|
-
pkey: string,
|
|
405
|
-
rpc: string,
|
|
406
|
-
chain: 'eth' | 'sol' | 'base' = 'eth',
|
|
407
|
-
tokenAddress?: string,
|
|
408
|
-
fastMode?: boolean
|
|
409
|
-
): Promise<string> {
|
|
410
|
-
console.log(`[ApiNow] Initiating transaction on chain: ${chain}`);
|
|
411
|
-
console.log(`[ApiNow] Transaction details:`, {
|
|
412
|
-
recipient: walletAddress,
|
|
413
|
-
amount: amount.toString(),
|
|
414
|
-
chain,
|
|
415
|
-
hasTokenAddress: !!tokenAddress,
|
|
416
|
-
fastMode
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
const handler = this.handlers[chain];
|
|
420
|
-
if (!handler) {
|
|
421
|
-
console.error(`[ApiNow] Unsupported chain: ${chain}`);
|
|
422
|
-
throw new Error(`Unsupported chain: ${chain}`);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
console.time(`[ApiNow] Transaction on ${chain}`);
|
|
426
|
-
try {
|
|
427
|
-
const txHash = await handler.buy(walletAddress, amount, pkey, rpc, tokenAddress, fastMode);
|
|
428
|
-
console.timeEnd(`[ApiNow] Transaction on ${chain}`);
|
|
429
|
-
console.log(`[ApiNow] Transaction successful with hash: ${txHash}`);
|
|
430
|
-
return txHash;
|
|
431
|
-
} catch (error) {
|
|
432
|
-
console.timeEnd(`[ApiNow] Transaction on ${chain}`);
|
|
433
|
-
console.error(`[ApiNow] Transaction failed:`, error);
|
|
434
|
-
console.error(`[ApiNow] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
435
|
-
throw error;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
async txResponse(
|
|
440
|
-
endpoint: string,
|
|
441
|
-
txHash: string,
|
|
442
|
-
opts: TxResponseOptions = {}
|
|
443
|
-
): Promise<any> {
|
|
444
|
-
console.log(`[ApiNow] Making API call with transaction hash`);
|
|
445
|
-
console.log(`[ApiNow] Call details:`, {
|
|
446
|
-
endpoint,
|
|
447
|
-
txHash,
|
|
448
|
-
method: opts.method || 'GET',
|
|
449
|
-
hasData: !!opts.data
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
if (!endpoint.startsWith('https://apinow.fun/api/endpoints/')) {
|
|
453
|
-
console.error(`[ApiNow] Invalid endpoint URL format: ${endpoint}`);
|
|
454
|
-
throw new Error('Invalid endpoint URL format');
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
const options = {
|
|
458
|
-
method: opts.method || 'GET',
|
|
459
|
-
headers: {
|
|
460
|
-
'x-transaction-hash': txHash,
|
|
461
|
-
...(opts.data && { 'Content-Type': 'application/json' })
|
|
462
|
-
},
|
|
463
|
-
...(opts.data && { body: JSON.stringify(opts.data) })
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
console.log(`[ApiNow] Request options:`, {
|
|
467
|
-
method: options.method,
|
|
468
|
-
headers: Object.keys(options.headers),
|
|
469
|
-
hasBody: !!options.body
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
console.time(`[ApiNow] API call with transaction hash`);
|
|
473
|
-
try {
|
|
474
|
-
const response = await fetch(endpoint, options);
|
|
475
|
-
console.timeEnd(`[ApiNow] API call with transaction hash`);
|
|
476
|
-
console.log(`[ApiNow] Response status: ${response.status}`);
|
|
477
|
-
|
|
478
|
-
if (!response.ok) {
|
|
479
|
-
console.error(`[ApiNow] API request failed: ${response.status} ${response.statusText}`);
|
|
480
|
-
const errorText = await response.text();
|
|
481
|
-
console.error(`[ApiNow] Error response body: ${errorText}`);
|
|
482
|
-
throw new Error(`API request failed: ${response.status}`);
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
const data = await response.json();
|
|
486
|
-
console.log(`[ApiNow] API call successful with data type: ${typeof data}`);
|
|
487
|
-
return data;
|
|
488
|
-
} catch (error) {
|
|
489
|
-
console.timeEnd(`[ApiNow] API call with transaction hash`);
|
|
490
|
-
console.error(`[ApiNow] API call failed:`, error);
|
|
491
|
-
console.error(`[ApiNow] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
492
|
-
throw error;
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
async infoBuyResponse(
|
|
497
|
-
endpoint: string,
|
|
498
|
-
pkey: string,
|
|
499
|
-
rpc: string,
|
|
500
|
-
opts: TxResponseOptions & { fastMode?: boolean } = {}
|
|
501
|
-
): Promise<any> {
|
|
502
|
-
console.log(`[ApiNow] Starting infoBuyResponse flow for endpoint: ${endpoint}`);
|
|
503
|
-
console.log(`[ApiNow] Options:`, {
|
|
504
|
-
method: opts.method,
|
|
505
|
-
hasData: !!opts.data,
|
|
506
|
-
fastMode: opts.fastMode
|
|
507
|
-
});
|
|
508
|
-
|
|
509
|
-
try {
|
|
510
|
-
console.time(`[ApiNow] Total infoBuyResponse flow`);
|
|
511
|
-
|
|
512
|
-
// Step 1: Get endpoint info
|
|
513
|
-
console.time(`[ApiNow] Get endpoint info`);
|
|
514
|
-
const info = await this.info(endpoint);
|
|
515
|
-
console.timeEnd(`[ApiNow] Get endpoint info`);
|
|
516
|
-
|
|
517
|
-
// Step 2: Calculate amount
|
|
518
|
-
console.log(`[ApiNow] Calculating transaction amount for chain: ${info.chain}`);
|
|
519
|
-
const amount = info.chain === 'sol'
|
|
520
|
-
? BigInt(Math.round(Number(info.requiredAmount) * LAMPORTS_PER_SOL))
|
|
521
|
-
: ethers.parseEther(info.requiredAmount);
|
|
522
|
-
console.log(`[ApiNow] Calculated amount: ${amount.toString()}`);
|
|
523
|
-
|
|
524
|
-
// Step 3: Execute transaction
|
|
525
|
-
console.time(`[ApiNow] Execute transaction`);
|
|
526
|
-
const txHash = await this.buy(
|
|
527
|
-
info.walletAddress,
|
|
528
|
-
amount,
|
|
529
|
-
pkey,
|
|
530
|
-
rpc,
|
|
531
|
-
info.chain,
|
|
532
|
-
info.tokenAddress,
|
|
533
|
-
opts.fastMode
|
|
534
|
-
);
|
|
535
|
-
console.timeEnd(`[ApiNow] Execute transaction`);
|
|
536
|
-
|
|
537
|
-
// Step 4: Make API call with transaction hash
|
|
538
|
-
console.log(`[ApiNow] Making API call with transaction hash: ${txHash}`);
|
|
539
|
-
console.time(`[ApiNow] API call with transaction hash`);
|
|
540
|
-
const response = await this.txResponse(endpoint, txHash, {
|
|
541
|
-
method: opts.method || info.httpMethod,
|
|
542
|
-
data: opts.data
|
|
543
|
-
});
|
|
544
|
-
console.timeEnd(`[ApiNow] API call with transaction hash`);
|
|
545
|
-
|
|
546
|
-
console.timeEnd(`[ApiNow] Total infoBuyResponse flow`);
|
|
547
|
-
console.log(`[ApiNow] infoBuyResponse flow completed successfully`);
|
|
548
|
-
|
|
549
|
-
return response;
|
|
550
|
-
} catch (error) {
|
|
551
|
-
console.timeEnd(`[ApiNow] Total infoBuyResponse flow`);
|
|
552
|
-
console.error(`[ApiNow] infoBuyResponse flow failed:`, error);
|
|
553
|
-
console.error(`[ApiNow] Error stack:`, error instanceof Error ? error.stack : 'No stack trace');
|
|
554
|
-
throw error;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
export default new ApiNow();
|
package/tsconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"declaration": true,
|
|
8
|
-
"outDir": "./dist",
|
|
9
|
-
"strict": true,
|
|
10
|
-
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true
|
|
12
|
-
},
|
|
13
|
-
"include": ["index.ts"],
|
|
14
|
-
"exclude": ["node_modules", "dist"]
|
|
15
|
-
}
|