@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.
@@ -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,2 +0,0 @@
1
- User-Agent: *
2
- Disallow:
@@ -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
- }
@@ -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]
@@ -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
-