@nosana/kit 1.0.7 ā 1.0.8
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/package.json +7 -2
- package/.gitlab-ci.yml +0 -54
- package/.prettierignore +0 -17
- package/eslint.config.js +0 -47
- package/examples/browser/.gitlab-ci.yml +0 -78
- package/examples/browser/FEATURES.md +0 -141
- package/examples/browser/QUICK_START.md +0 -76
- package/examples/browser/README.md +0 -182
- package/examples/browser/app.vue +0 -1840
- package/examples/browser/assets/css/main.css +0 -7
- package/examples/browser/nuxt.config.ts +0 -30
- package/examples/browser/package-lock.json +0 -12230
- package/examples/browser/package.json +0 -31
- package/examples/browser/public/favicon.ico +0 -0
- package/examples/browser/public/robots.txt +0 -2
- package/examples/browser/start.sh +0 -38
- package/examples/browser/tailwind.config.js +0 -26
- package/examples/node/README.md +0 -261
- package/examples/node/example-keypair.json +0 -1
- package/examples/node/monitor.ts +0 -143
- package/examples/node/nos-service.ts +0 -117
- package/examples/node/package-lock.json +0 -589
- package/examples/node/package.json +0 -20
- package/examples/node/post-job.ts +0 -160
- package/examples/node/retrieve.ts +0 -18
- package/examples/node/set-wallet.ts +0 -87
- package/examples/node/stake-program.ts +0 -84
- package/scripts/generate-clients.ts +0 -33
- package/vitest.config.ts +0 -31
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "nosana-sdk-browser-playground",
|
|
3
|
-
"description": "Interactive documentation and testing environment for the Nosana SDK",
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"private": true,
|
|
6
|
-
"type": "module",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"build": "nuxt build",
|
|
9
|
-
"dev": "nuxt dev",
|
|
10
|
-
"generate": "nuxt generate",
|
|
11
|
-
"preview": "nuxt preview",
|
|
12
|
-
"postinstall": "nuxt prepare",
|
|
13
|
-
"start": "nuxt dev"
|
|
14
|
-
},
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"@headlessui/vue": "^1.7.23",
|
|
17
|
-
"@heroicons/vue": "^2.2.0",
|
|
18
|
-
"@nosana/kit": "^0.1.2",
|
|
19
|
-
"@nuxtjs/tailwindcss": "^7.0.0-beta.0",
|
|
20
|
-
"@tailwindcss/typography": "^0.5.16",
|
|
21
|
-
"nuxt": "^3.17.4",
|
|
22
|
-
"vue": "^3.5.15",
|
|
23
|
-
"vue-router": "^4.5.1"
|
|
24
|
-
},
|
|
25
|
-
"devDependencies": {
|
|
26
|
-
"@tailwindcss/postcss": "^4.1.8",
|
|
27
|
-
"autoprefixer": "^10.4.21",
|
|
28
|
-
"postcss": "^8.5.4",
|
|
29
|
-
"tailwindcss": "^4.1.8"
|
|
30
|
-
}
|
|
31
|
-
}
|
|
Binary file
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
echo "š Starting Nosana SDK Browser Playground..."
|
|
4
|
-
echo ""
|
|
5
|
-
|
|
6
|
-
# Check if Node.js is installed
|
|
7
|
-
if ! command -v node &> /dev/null; then
|
|
8
|
-
echo "ā Node.js is not installed. Please install Node.js 20.18.0 or higher."
|
|
9
|
-
exit 1
|
|
10
|
-
fi
|
|
11
|
-
|
|
12
|
-
# Check Node.js version
|
|
13
|
-
NODE_VERSION=$(node -v | cut -d'v' -f2)
|
|
14
|
-
REQUIRED_VERSION="20.18.0"
|
|
15
|
-
|
|
16
|
-
if [ "$(printf '%s\n' "$REQUIRED_VERSION" "$NODE_VERSION" | sort -V | head -n1)" != "$REQUIRED_VERSION" ]; then
|
|
17
|
-
echo "ā ļø Warning: Node.js version $NODE_VERSION detected. Recommended version is $REQUIRED_VERSION or higher."
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
# Check if we're in the right directory
|
|
21
|
-
if [ ! -f "package.json" ]; then
|
|
22
|
-
echo "ā Please run this script from the examples/browser directory"
|
|
23
|
-
exit 1
|
|
24
|
-
fi
|
|
25
|
-
|
|
26
|
-
# Install dependencies if node_modules doesn't exist
|
|
27
|
-
if [ ! -d "node_modules" ]; then
|
|
28
|
-
echo "š¦ Installing dependencies..."
|
|
29
|
-
npm install
|
|
30
|
-
echo ""
|
|
31
|
-
fi
|
|
32
|
-
|
|
33
|
-
echo "š Starting development server..."
|
|
34
|
-
echo "š Open http://localhost:3000 in your browser"
|
|
35
|
-
echo "š Press Ctrl+C to stop the server"
|
|
36
|
-
echo ""
|
|
37
|
-
|
|
38
|
-
npm run dev
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/** @type {import('tailwindcss').Config} */
|
|
2
|
-
module.exports = {
|
|
3
|
-
content: [
|
|
4
|
-
"./components/**/*.{js,vue,ts}",
|
|
5
|
-
"./layouts/**/*.vue",
|
|
6
|
-
"./pages/**/*.vue",
|
|
7
|
-
"./plugins/**/*.{js,ts}",
|
|
8
|
-
"./app.vue",
|
|
9
|
-
"./error.vue"
|
|
10
|
-
],
|
|
11
|
-
theme: {
|
|
12
|
-
extend: {
|
|
13
|
-
colors: {
|
|
14
|
-
terminal: {
|
|
15
|
-
bg: '#1a202c',
|
|
16
|
-
text: '#68d391',
|
|
17
|
-
error: '#fc8181',
|
|
18
|
-
success: '#68d391',
|
|
19
|
-
info: '#63b3ed',
|
|
20
|
-
warning: '#f6e05e'
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
plugins: [],
|
|
26
|
-
}
|
package/examples/node/README.md
DELETED
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
# Nosana Kit Node.js Examples
|
|
2
|
-
|
|
3
|
-
This directory contains Node.js examples for using the Nosana Kit.
|
|
4
|
-
|
|
5
|
-
## Set Wallet Example
|
|
6
|
-
|
|
7
|
-
The `set-wallet.ts` example demonstrates various ways to initialize and set a wallet for the Nosana Client.
|
|
8
|
-
|
|
9
|
-
### Supported Wallet Formats
|
|
10
|
-
|
|
11
|
-
The `setWallet` method supports the following input formats:
|
|
12
|
-
|
|
13
|
-
1. **File Path**: Path to a JSON file containing a keypair array
|
|
14
|
-
2. **JSON Array String**: A string containing a JSON array of numbers representing the keypair
|
|
15
|
-
3. **Number Array**: A direct array of numbers representing the keypair
|
|
16
|
-
4. **Base58 String**: A base58-encoded private key
|
|
17
|
-
5. **Environment Variable**: Name of an environment variable containing the keypair data
|
|
18
|
-
6. **KeyPairSigner Object**: An existing KeyPairSigner instance
|
|
19
|
-
|
|
20
|
-
### Running the Example
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
# Navigate to the examples/node directory
|
|
24
|
-
cd examples/node
|
|
25
|
-
|
|
26
|
-
# Install dependencies
|
|
27
|
-
npm install
|
|
28
|
-
|
|
29
|
-
# Run the set-wallet example
|
|
30
|
-
npx ts-node set-wallet.ts
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Example Usage
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
import { NosanaClient, NosanaNetwork } from '@nosana/kit';
|
|
37
|
-
|
|
38
|
-
const client = new NosanaClient(NosanaNetwork.DEVNET);
|
|
39
|
-
|
|
40
|
-
// From file path
|
|
41
|
-
await client.setWallet('./path/to/keypair.json');
|
|
42
|
-
|
|
43
|
-
// From JSON string
|
|
44
|
-
await client.setWallet('[174,47,154,16,...]');
|
|
45
|
-
|
|
46
|
-
// From number array
|
|
47
|
-
await client.setWallet([174, 47, 154, 16, ...]);
|
|
48
|
-
|
|
49
|
-
// From base58 string
|
|
50
|
-
await client.setWallet('base58EncodedPrivateKey');
|
|
51
|
-
|
|
52
|
-
// From environment variable
|
|
53
|
-
process.env.WALLET_KEY = '[174,47,154,16,...]';
|
|
54
|
-
await client.setWallet('WALLET_KEY');
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Quick Test
|
|
58
|
-
|
|
59
|
-
You can test the setWallet functionality manually by creating a simple test file:
|
|
60
|
-
|
|
61
|
-
```javascript
|
|
62
|
-
// test-setwallet.js
|
|
63
|
-
const { NosanaClient, NosanaNetwork } = require('@nosana/kit');
|
|
64
|
-
|
|
65
|
-
async function testSetWallet() {
|
|
66
|
-
const client = new NosanaClient(NosanaNetwork.DEVNET);
|
|
67
|
-
|
|
68
|
-
// Test with a sample keypair array
|
|
69
|
-
const sampleKeypair = [
|
|
70
|
-
174, 47, 154, 16, 202, 193, 206, 113, 199, 190, 53, 133, 169, 175, 31, 56, 222, 53, 138,
|
|
71
|
-
189, 224, 216, 117, 173, 10, 149, 53, 45, 73, 251, 237, 246, 15, 185, 186, 82, 177, 240,
|
|
72
|
-
148, 69, 241, 227, 167, 80, 141, 89, 240, 121, 121, 35, 172, 247, 68, 251, 226, 218, 48,
|
|
73
|
-
63, 176, 109, 168, 89, 238, 135,
|
|
74
|
-
];
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const wallet = await client.setWallet(sampleKeypair);
|
|
78
|
-
console.log('ā
Wallet set successfully!');
|
|
79
|
-
console.log('Address:', wallet?.address);
|
|
80
|
-
} catch (error) {
|
|
81
|
-
console.error('ā Error:', error.message);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
testSetWallet();
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Run it with: `node test-setwallet.js`
|
|
89
|
-
|
|
90
|
-
### Error Handling
|
|
91
|
-
|
|
92
|
-
The `setWallet` method tries multiple conversion methods in sequence. If all methods fail, it throws a `NosanaError` with the code `WALLET_CONVERSION_ERROR`.
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
try {
|
|
96
|
-
await client.setWallet(walletData);
|
|
97
|
-
console.log('Wallet set successfully:', client.wallet?.address);
|
|
98
|
-
} catch (error) {
|
|
99
|
-
if (error instanceof NosanaError && error.code === ErrorCodes.WALLET_CONVERSION_ERROR) {
|
|
100
|
-
console.error('Failed to set wallet:', error.message);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Implementation Details
|
|
106
|
-
|
|
107
|
-
The `setWallet` method in `src/index.ts` implements the following logic:
|
|
108
|
-
|
|
109
|
-
1. **KeyPairSigner Check**: If the input is already a KeyPairSigner object, it's used directly
|
|
110
|
-
2. **File Path Processing**: For strings that look like file paths (absolute, `./`, or `../`), it attempts to load the keypair from file
|
|
111
|
-
3. **Environment Variable**: Tries to load from environment variables (both JSON and base58 formats)
|
|
112
|
-
4. **JSON Parsing**: Attempts to parse JSON array strings
|
|
113
|
-
5. **Base58 Decoding**: Tries to decode base58-encoded strings
|
|
114
|
-
6. **Array Processing**: Converts number arrays to Uint8Array for keypair creation
|
|
115
|
-
|
|
116
|
-
### Unit Tests
|
|
117
|
-
|
|
118
|
-
Comprehensive unit tests have been created in `src/__tests__/setWallet.test.ts` to cover:
|
|
119
|
-
|
|
120
|
-
- ā
KeyPairSigner input handling
|
|
121
|
-
- ā
File path validation and loading
|
|
122
|
-
- ā
Environment variable processing
|
|
123
|
-
- ā
JSON array string parsing
|
|
124
|
-
- ā
Base58 string decoding
|
|
125
|
-
- ā
Number array conversion
|
|
126
|
-
- ā
Error handling for invalid inputs
|
|
127
|
-
- ā
File path validation (absolute vs relative paths)
|
|
128
|
-
|
|
129
|
-
**Note**: Due to Jest/TypeScript configuration complexities with the `gill/dist/node` imports, running the tests may require additional setup. The functionality works correctly at runtime.
|
|
130
|
-
|
|
131
|
-
## NOS Token Service Example
|
|
132
|
-
|
|
133
|
-
The `nos-service.ts` example demonstrates how to interact with NOS token accounts using the NosService.
|
|
134
|
-
|
|
135
|
-
### Features
|
|
136
|
-
|
|
137
|
-
1. **Get all NOS token holders** - Fetch all token accounts holding NOS tokens (excludes zero balances by default)
|
|
138
|
-
2. **Include zero balance accounts** - Optional flag to include accounts with zero balance
|
|
139
|
-
3. **Exclude PDA accounts** - Filter out smart contract-owned token accounts (PDAs)
|
|
140
|
-
4. **Get token account for address** - Retrieve token account details for a specific owner
|
|
141
|
-
5. **Get balance** - Convenience method to get just the NOS balance
|
|
142
|
-
6. **Batch queries** - Fetch balances for multiple addresses
|
|
143
|
-
7. **Filter and analyze** - Find large holders and analyze token distribution
|
|
144
|
-
|
|
145
|
-
### Running the Example
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
# Navigate to the examples/node directory
|
|
149
|
-
cd examples/node
|
|
150
|
-
|
|
151
|
-
# Install dependencies
|
|
152
|
-
npm install
|
|
153
|
-
|
|
154
|
-
# Run the nos-service example
|
|
155
|
-
npm run nos-service
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### Example Usage
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
import { NosanaClient, NosanaNetwork } from '@nosana/kit';
|
|
162
|
-
|
|
163
|
-
const client = new NosanaClient(NosanaNetwork.MAINNET);
|
|
164
|
-
|
|
165
|
-
// Get all token holders (single RPC call, excludes zero balances by default)
|
|
166
|
-
const holders = await client.nos.getAllTokenHolders();
|
|
167
|
-
console.log(`Found ${holders.length} NOS token holders`);
|
|
168
|
-
|
|
169
|
-
// Include accounts with zero balance
|
|
170
|
-
const allAccounts = await client.nos.getAllTokenHolders({ includeZeroBalance: true });
|
|
171
|
-
console.log(`Total accounts: ${allAccounts.length}`);
|
|
172
|
-
|
|
173
|
-
// Exclude PDA accounts (smart contract-owned accounts)
|
|
174
|
-
const userAccounts = await client.nos.getAllTokenHolders({ excludePdaAccounts: true });
|
|
175
|
-
console.log(`User-owned accounts: ${userAccounts.length}`);
|
|
176
|
-
|
|
177
|
-
// Get token account for specific address
|
|
178
|
-
const account = await client.nos.getTokenAccountForAddress('owner-address');
|
|
179
|
-
if (account) {
|
|
180
|
-
console.log(`Balance: ${account.uiAmount} NOS`);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Get just the balance (convenience method)
|
|
184
|
-
const balance = await client.nos.getBalance('owner-address');
|
|
185
|
-
console.log(`Balance: ${balance} NOS`);
|
|
186
|
-
|
|
187
|
-
// Filter holders by minimum balance
|
|
188
|
-
const largeHolders = holders.filter(holder => holder.uiAmount >= 1000);
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### Use Cases
|
|
192
|
-
|
|
193
|
-
- **Analytics**: Analyze token distribution and holder statistics
|
|
194
|
-
- **Airdrops**: Get list of all token holders for airdrop campaigns
|
|
195
|
-
- **Balance checks**: Check NOS balances for specific addresses
|
|
196
|
-
- **Leaderboards**: Create holder leaderboards sorted by balance
|
|
197
|
-
- **Monitoring**: Track large holder movements
|
|
198
|
-
|
|
199
|
-
## Stake Program Example
|
|
200
|
-
|
|
201
|
-
The `stake-program.ts` example demonstrates how to interact with Nosana staking accounts using the StakeProgram.
|
|
202
|
-
|
|
203
|
-
### Features
|
|
204
|
-
|
|
205
|
-
1. **Get all stake accounts** - Fetch all staking accounts on-chain
|
|
206
|
-
2. **Get single stake** - Fetch details of a specific stake account
|
|
207
|
-
3. **Get multiple stakes** - Fetch multiple stake accounts by address
|
|
208
|
-
4. **Analyze distribution** - Calculate staking statistics (total, average, largest)
|
|
209
|
-
|
|
210
|
-
### Running the Example
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
# Navigate to the examples/node directory
|
|
214
|
-
cd examples/node
|
|
215
|
-
|
|
216
|
-
# Install dependencies
|
|
217
|
-
npm install
|
|
218
|
-
|
|
219
|
-
# Run the stake-program example
|
|
220
|
-
npm run stake-program
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Example Usage
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
import { NosanaClient, NosanaNetwork } from '@nosana/kit';
|
|
227
|
-
|
|
228
|
-
const client = new NosanaClient(NosanaNetwork.MAINNET);
|
|
229
|
-
|
|
230
|
-
// Get all stake accounts
|
|
231
|
-
const allStakes = await client.stake.all();
|
|
232
|
-
console.log(`Found ${allStakes.length} stake accounts`);
|
|
233
|
-
|
|
234
|
-
// Get single stake account
|
|
235
|
-
const stake = await client.stake.get('stake-account-address');
|
|
236
|
-
console.log(`Staked amount: ${stake.amount}`);
|
|
237
|
-
console.log(`xNOS tokens: ${stake.xnos}`);
|
|
238
|
-
|
|
239
|
-
// Analyze staking distribution
|
|
240
|
-
const totalStaked = allStakes.reduce((sum, s) => sum + s.amount, 0);
|
|
241
|
-
const averageStake = totalStaked / allStakes.length;
|
|
242
|
-
console.log(`Total staked: ${totalStaked.toLocaleString()}`);
|
|
243
|
-
console.log(`Average stake: ${averageStake.toLocaleString()}`);
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
## Other Examples
|
|
247
|
-
|
|
248
|
-
- `retrieve.ts` - Example of retrieving job data
|
|
249
|
-
- `monitor.ts` - Example of monitoring jobs
|
|
250
|
-
|
|
251
|
-
## Running Tests
|
|
252
|
-
|
|
253
|
-
To run all tests:
|
|
254
|
-
```bash
|
|
255
|
-
npm test
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
To run specific tests:
|
|
259
|
-
```bash
|
|
260
|
-
npm test -- --testNamePattern="setWallet"
|
|
261
|
-
```
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[66,240,117,68,169,30,179,62,57,123,28,249,122,218,186,173,196,222,208,58,126,168,32,91,126,64,102,33,220,51,49,97,6,197,228,206,210,117,23,184,89,48,217,110,194,137,242,129,112,23,140,120,148,249,210,18,105,192,40,197,250,132,40,149]
|
package/examples/node/monitor.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { NosanaClient, NosanaNetwork, Job, Market, Run } from '@nosana/kit';
|
|
2
|
-
import { promises as fs } from 'fs';
|
|
3
|
-
|
|
4
|
-
// Type for storing accounts in a more readable format
|
|
5
|
-
type AccountData = {
|
|
6
|
-
address: string;
|
|
7
|
-
data: Job | Run | Market;
|
|
8
|
-
lastUpdated: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
async function main() {
|
|
12
|
-
// Initialize the Nosana client
|
|
13
|
-
const client = new NosanaClient(NosanaNetwork.MAINNET);
|
|
14
|
-
|
|
15
|
-
console.log('Starting job account monitoring...');
|
|
16
|
-
|
|
17
|
-
// Storage for accounts
|
|
18
|
-
const jobAccounts = new Map<string, AccountData>();
|
|
19
|
-
const runAccounts = new Map<string, AccountData>();
|
|
20
|
-
const marketAccounts = new Map<string, AccountData>();
|
|
21
|
-
|
|
22
|
-
// Helper function to save accounts to file
|
|
23
|
-
const saveAccountsToFile = async () => {
|
|
24
|
-
const data = {
|
|
25
|
-
jobAccounts: Object.fromEntries(jobAccounts),
|
|
26
|
-
runAccounts: Object.fromEntries(runAccounts),
|
|
27
|
-
marketAccounts: Object.fromEntries(marketAccounts),
|
|
28
|
-
lastUpdated: new Date().toISOString(),
|
|
29
|
-
totalAccounts: jobAccounts.size + runAccounts.size + marketAccounts.size
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
await fs.writeFile('accounts.json', JSON.stringify(data, null, 2));
|
|
34
|
-
console.log(`š¾ Saved ${data.totalAccounts} accounts to accounts.json`);
|
|
35
|
-
} catch (error) {
|
|
36
|
-
console.error('Failed to save accounts to file:', error);
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// Load existing accounts if file exists
|
|
41
|
-
try {
|
|
42
|
-
const existingData = await fs.readFile('accounts.json', 'utf-8');
|
|
43
|
-
const parsed = JSON.parse(existingData);
|
|
44
|
-
|
|
45
|
-
if (parsed.jobAccounts) {
|
|
46
|
-
for (const [key, value] of Object.entries(parsed.jobAccounts)) {
|
|
47
|
-
jobAccounts.set(key, value as AccountData);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (parsed.runAccounts) {
|
|
51
|
-
for (const [key, value] of Object.entries(parsed.runAccounts)) {
|
|
52
|
-
runAccounts.set(key, value as AccountData);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (parsed.marketAccounts) {
|
|
56
|
-
for (const [key, value] of Object.entries(parsed.marketAccounts)) {
|
|
57
|
-
marketAccounts.set(key, value as AccountData);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
console.log(`š Loaded existing accounts: ${jobAccounts.size} jobs, ${runAccounts.size} runs, ${marketAccounts.size} markets`);
|
|
62
|
-
} catch (error) {
|
|
63
|
-
console.log('š Starting with empty account storage (no existing file found)');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
// Start monitoring job account updates with callback functions
|
|
68
|
-
const stopMonitoring = await client.jobs.monitor({
|
|
69
|
-
onJobAccount: async (jobAccount: Job) => {
|
|
70
|
-
const accountData: AccountData = {
|
|
71
|
-
address: jobAccount.address.toString(),
|
|
72
|
-
data: jobAccount,
|
|
73
|
-
lastUpdated: new Date().toISOString()
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
jobAccounts.set(jobAccount.address.toString(), accountData);
|
|
77
|
-
console.log(`š Job account updated: ${jobAccount.address.toString()}`);
|
|
78
|
-
|
|
79
|
-
// Save to file after each update
|
|
80
|
-
await saveAccountsToFile();
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
onRunAccount: async (runAccount: Run) => {
|
|
84
|
-
const accountData: AccountData = {
|
|
85
|
-
address: runAccount.address.toString(),
|
|
86
|
-
data: runAccount,
|
|
87
|
-
lastUpdated: new Date().toISOString()
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
runAccounts.set(runAccount.address.toString(), accountData);
|
|
91
|
-
console.log(`š Run account updated: ${runAccount.address.toString()}`);
|
|
92
|
-
|
|
93
|
-
// Save to file after each update
|
|
94
|
-
await saveAccountsToFile();
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
onMarketAccount: async (marketAccount: Market) => {
|
|
98
|
-
const accountData: AccountData = {
|
|
99
|
-
address: marketAccount.address.toString(),
|
|
100
|
-
data: marketAccount,
|
|
101
|
-
lastUpdated: new Date().toISOString()
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
marketAccounts.set(marketAccount.address.toString(), accountData);
|
|
105
|
-
console.log(`šŖ Market account updated: ${marketAccount.address.toString()}`);
|
|
106
|
-
|
|
107
|
-
// Save to file after each update
|
|
108
|
-
await saveAccountsToFile();
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
onError: async (error: Error, accountType?: string) => {
|
|
112
|
-
console.error(`ā Error processing ${accountType || 'unknown'} account:`, error.message);
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
console.log('ā
Job account monitoring started successfully!');
|
|
117
|
-
console.log('š Monitoring will save account updates to accounts.json');
|
|
118
|
-
console.log('š Watching for job, run, and market account updates...');
|
|
119
|
-
console.log('ā¹ļø Press Ctrl+C to stop monitoring...');
|
|
120
|
-
|
|
121
|
-
// Handle graceful shutdown
|
|
122
|
-
process.on('SIGINT', async () => {
|
|
123
|
-
console.log('\nš Stopping job account monitoring...');
|
|
124
|
-
stopMonitoring();
|
|
125
|
-
|
|
126
|
-
// Final save
|
|
127
|
-
await saveAccountsToFile();
|
|
128
|
-
|
|
129
|
-
console.log('ā
Monitoring stopped. Final data saved. Exiting...');
|
|
130
|
-
process.exit(0);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Keep the process running
|
|
134
|
-
await new Promise(() => { });
|
|
135
|
-
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error('ā Failed to start job account monitoring:', error);
|
|
138
|
-
process.exit(1);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Run the example
|
|
143
|
-
main().catch(console.error);
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Example: Using the NosService to interact with NOS token accounts
|
|
3
|
-
*
|
|
4
|
-
* This example demonstrates how to use the NosService to:
|
|
5
|
-
* 1. Get all NOS token holders
|
|
6
|
-
* 2. Get a specific token account for an address
|
|
7
|
-
* 3. Get the NOS balance for an address
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { NosanaClient, NosanaNetwork } from '@nosana/kit';
|
|
11
|
-
|
|
12
|
-
async function main() {
|
|
13
|
-
// Initialize the Nosana client (use MAINNET for real data)
|
|
14
|
-
const client = new NosanaClient(NosanaNetwork.MAINNET);
|
|
15
|
-
|
|
16
|
-
// Example 1: Get all NOS token holders (excludes zero balance by default)
|
|
17
|
-
console.log('Fetching all NOS token holders...');
|
|
18
|
-
try {
|
|
19
|
-
const holders = await client.nos.getAllTokenHolders();
|
|
20
|
-
|
|
21
|
-
console.log(`Found ${holders.length} NOS token holders (with non-zero balances)`);
|
|
22
|
-
|
|
23
|
-
// Display first 5 holders
|
|
24
|
-
holders.slice(0, 5).forEach((holder, index) => {
|
|
25
|
-
console.log(`\nHolder ${index + 1}:`);
|
|
26
|
-
console.log(` Token Account: ${holder.pubkey}`);
|
|
27
|
-
console.log(` Owner: ${holder.owner}`);
|
|
28
|
-
console.log(` Balance: ${holder.uiAmount} NOS`);
|
|
29
|
-
console.log(` Raw Amount: ${holder.amount.toString()}`);
|
|
30
|
-
console.log(` Decimals: ${holder.decimals}`);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Include zero balance accounts
|
|
34
|
-
console.log('\nFetching all accounts including zero balances...');
|
|
35
|
-
const allAccounts = await client.token.getAllTokenHolders({ includeZeroBalance: true });
|
|
36
|
-
console.log(`Total accounts (including zero balance): ${allAccounts.length}`);
|
|
37
|
-
console.log(`Accounts with zero balance: ${allAccounts.length - holders.length}`);
|
|
38
|
-
|
|
39
|
-
// Exclude PDA accounts (smart contract-owned accounts)
|
|
40
|
-
console.log('\nFetching user-owned accounts only (excluding PDAs)...');
|
|
41
|
-
const userAccounts = await client.token.getAllTokenHolders({ excludePdaAccounts: true });
|
|
42
|
-
console.log(`User-owned accounts: ${userAccounts.length}`);
|
|
43
|
-
console.log(`PDA accounts: ${holders.length - userAccounts.length}`);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
console.error('Error fetching token holders:', error);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Example 2: Get token account for a specific address
|
|
49
|
-
const ownerAddress = 'YourWalletAddressHere';
|
|
50
|
-
|
|
51
|
-
console.log(`\nFetching NOS token account for ${ownerAddress}...`);
|
|
52
|
-
try {
|
|
53
|
-
const account = await client.nos.getTokenAccountForAddress(ownerAddress);
|
|
54
|
-
|
|
55
|
-
if (account) {
|
|
56
|
-
console.log('Token Account found:');
|
|
57
|
-
console.log(` Account Address: ${account.pubkey}`);
|
|
58
|
-
console.log(` Owner: ${account.owner}`);
|
|
59
|
-
console.log(` Mint: ${account.mint}`);
|
|
60
|
-
console.log(` Balance: ${account.uiAmount} NOS`);
|
|
61
|
-
console.log(` Raw Amount: ${account.amount.toString()}`);
|
|
62
|
-
console.log(` Decimals: ${account.decimals}`);
|
|
63
|
-
} else {
|
|
64
|
-
console.log('No NOS token account found for this address');
|
|
65
|
-
}
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.error('Error fetching token account:', error);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Example 3: Get just the balance (convenience method)
|
|
71
|
-
console.log(`\nFetching NOS balance for ${ownerAddress}...`);
|
|
72
|
-
try {
|
|
73
|
-
const balance = await client.nos.getBalance(ownerAddress);
|
|
74
|
-
console.log(`Balance: ${balance} NOS`);
|
|
75
|
-
} catch (error) {
|
|
76
|
-
console.error('Error fetching balance:', error);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Example 4: Working with multiple addresses
|
|
80
|
-
const addresses = [
|
|
81
|
-
'Address1Here',
|
|
82
|
-
'Address2Here',
|
|
83
|
-
'Address3Here',
|
|
84
|
-
];
|
|
85
|
-
|
|
86
|
-
console.log('\nFetching balances for multiple addresses...');
|
|
87
|
-
for (const addr of addresses) {
|
|
88
|
-
try {
|
|
89
|
-
const balance = await client.nos.getBalance(addr);
|
|
90
|
-
console.log(`${addr}: ${balance} NOS`);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error(`Error fetching balance for ${addr}:`, error);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Example 5: Filter holders by minimum balance
|
|
97
|
-
console.log('\nFinding holders with at least 1000 NOS...');
|
|
98
|
-
try {
|
|
99
|
-
const holders = await client.nos.getAllTokenHolders();
|
|
100
|
-
const largeHolders = holders.filter(holder => holder.uiAmount >= 1000);
|
|
101
|
-
|
|
102
|
-
console.log(`Found ${largeHolders.length} holders with >= 1000 NOS`);
|
|
103
|
-
|
|
104
|
-
// Sort by balance descending
|
|
105
|
-
const sorted = largeHolders.sort((a, b) => b.uiAmount - a.uiAmount);
|
|
106
|
-
|
|
107
|
-
// Display top 10
|
|
108
|
-
sorted.slice(0, 10).forEach((holder, index) => {
|
|
109
|
-
console.log(`${index + 1}. ${holder.owner}: ${holder.uiAmount.toLocaleString()} NOS`);
|
|
110
|
-
});
|
|
111
|
-
} catch (error) {
|
|
112
|
-
console.error('Error analyzing holders:', error);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
main().catch(console.error);
|
|
117
|
-
|