@xandeum/web3.js 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -6
- package/archbee.yaml +55 -0
- package/dist/armageddon.js +9 -1
- package/dist/assignCoowner.d.ts +12 -0
- package/dist/assignCoowner.js +89 -0
- package/dist/bigbang.d.ts +2 -1
- package/dist/bigbang.js +17 -3
- package/dist/const.d.ts +1 -0
- package/dist/const.js +2 -1
- package/dist/copyPath.js +9 -1
- package/dist/createDirectory.js +10 -2
- package/dist/createFile.js +10 -2
- package/dist/exists.js +7 -5
- package/dist/find.d.ts +22 -0
- package/dist/find.js +88 -0
- package/dist/getMetadata.js +7 -5
- package/dist/getXandeumResult.d.ts +15 -0
- package/dist/getXandeumResult.js +115 -0
- package/dist/helpers.d.ts +56 -0
- package/dist/helpers.js +80 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +7 -1
- package/dist/listDirectoryEntery.js +7 -5
- package/dist/move.d.ts +14 -0
- package/dist/move.js +96 -0
- package/dist/pdaHelpers.d.ts +57 -0
- package/dist/pdaHelpers.js +83 -0
- package/dist/peek.js +9 -1
- package/dist/poke.js +9 -1
- package/dist/removeDirectory.js +9 -1
- package/dist/removeFile.js +9 -1
- package/dist/renamePath.js +9 -1
- package/dist/webSocket.d.ts +1 -1
- package/dist/webSocket.js +16 -3
- package/docs/html/assets/highlight.css +92 -0
- package/docs/html/assets/navigation.js +1 -0
- package/docs/html/assets/search.js +1 -0
- package/docs/{functions → html/functions}/armageddon.html +3 -3
- package/docs/html/functions/assignCoowner.html +8 -0
- package/docs/html/functions/bigbang.html +5 -0
- package/docs/{functions → html/functions}/copyPath.html +2 -8
- package/docs/{functions → html/functions}/createDirectory.html +2 -8
- package/docs/{functions → html/functions}/createFile.html +2 -9
- package/docs/{functions → html/functions}/exists.html +4 -4
- package/docs/html/functions/find.html +10 -0
- package/docs/html/functions/getMetadata.html +10 -0
- package/docs/html/functions/getXandeumResult.html +9 -0
- package/docs/{functions → html/functions}/listDirectoryEntry.html +4 -4
- package/docs/html/functions/move.html +9 -0
- package/docs/{functions → html/functions}/peek.html +2 -10
- package/docs/{functions → html/functions}/poke.html +2 -10
- package/docs/{functions → html/functions}/removeDirectory.html +2 -8
- package/docs/{functions → html/functions}/removeFile.html +2 -8
- package/docs/{functions → html/functions}/renamePath.html +3 -9
- package/docs/{functions → html/functions}/subscribeResult.html +4 -4
- package/docs/html/functions/unsubscribeResult.html +6 -0
- package/docs/{hierarchy.html → html/hierarchy.html} +1 -1
- package/docs/html/index.html +62 -0
- package/docs/html/modules.html +1 -0
- package/docs/markdown/README.md +166 -2
- package/docs/markdown/functions/armageddon.md +2 -3
- package/docs/markdown/functions/assignCoowner.md +46 -0
- package/docs/markdown/functions/bigbang.md +9 -3
- package/docs/markdown/functions/copyPath.md +2 -2
- package/docs/markdown/functions/createDirectory.md +2 -2
- package/docs/markdown/functions/createFile.md +2 -2
- package/docs/markdown/functions/exists.md +8 -8
- package/docs/markdown/functions/find.md +44 -0
- package/docs/markdown/functions/getMetadata.md +8 -8
- package/docs/markdown/functions/getXandeumResult.md +38 -0
- package/docs/markdown/functions/listDirectoryEntry.md +8 -8
- package/docs/markdown/functions/move.md +55 -0
- package/docs/markdown/functions/peek.md +2 -2
- package/docs/markdown/functions/poke.md +2 -2
- package/docs/markdown/functions/removeDirectory.md +2 -2
- package/docs/markdown/functions/removeFile.md +2 -2
- package/docs/markdown/functions/renamePath.md +2 -2
- package/docs/markdown/functions/subscribeResult.md +8 -8
- package/docs/markdown/functions/unsubscribeResult.md +8 -8
- package/docs/markdown/globals.md +6 -2
- package/package.json +3 -3
- package/src/armageddon.ts +8 -0
- package/src/assignCoowner.ts +49 -0
- package/src/bigbang.ts +13 -2
- package/src/const.ts +3 -1
- package/src/copyPath.ts +8 -1
- package/src/createDirectory.ts +9 -2
- package/src/createFile.ts +9 -3
- package/src/exists.ts +2 -1
- package/src/find.ts +53 -0
- package/src/getMetadata.ts +2 -1
- package/src/getXandeumResult.ts +67 -0
- package/src/helpers.ts +85 -0
- package/src/index.ts +5 -1
- package/src/listDirectoryEntery.ts +2 -1
- package/src/move.ts +62 -0
- package/src/peek.ts +8 -1
- package/src/poke.ts +8 -1
- package/src/removeDirectory.ts +8 -2
- package/src/removeFile.ts +8 -2
- package/src/renamePath.ts +8 -2
- package/src/webSocket.ts +18 -5
- package/typedoc.json +3 -4
- package/docs/assets/highlight.css +0 -22
- package/docs/assets/navigation.js +0 -1
- package/docs/assets/search.js +0 -1
- package/docs/functions/bigbang.html +0 -4
- package/docs/functions/getMetadata.html +0 -10
- package/docs/functions/unsubscribeResult.html +0 -6
- package/docs/index.html +0 -2
- package/docs/modules.html +0 -1
- /package/docs/{.nojekyll → html/.nojekyll} +0 -0
- /package/docs/{assets → html/assets}/hierarchy.js +0 -0
- /package/docs/{assets → html/assets}/icons.js +0 -0
- /package/docs/{assets → html/assets}/icons.svg +0 -0
- /package/docs/{assets → html/assets}/main.js +0 -0
- /package/docs/{assets → html/assets}/style.css +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
2
|
+
import { programId } from './const'
|
|
3
|
+
import BN from 'bn.js'
|
|
4
|
+
import { getFeeDistributorPda } from './helpers.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Constructs a Solana transaction to assign a co-owner to a file or directory
|
|
8
|
+
* identified by a file system ID (`fsid`).
|
|
9
|
+
*
|
|
10
|
+
* @param fsid - A stringified integer representing the file system ID where the co-owner is to be assigned.
|
|
11
|
+
* @param path - The path within the file system.
|
|
12
|
+
* @param coowner - The public key of the co-owner to be assigned.
|
|
13
|
+
* @param wallet - The public key of the wallet that will sign and authorize the transaction.
|
|
14
|
+
* @returns A Promise that resolves to a Solana `Transaction` object containing the assignCoowner instruction.
|
|
15
|
+
*/
|
|
16
|
+
export async function assignCoowner (
|
|
17
|
+
fsid: string,
|
|
18
|
+
path: string,
|
|
19
|
+
coowner: PublicKey,
|
|
20
|
+
wallet: PublicKey
|
|
21
|
+
): Promise<Transaction> {
|
|
22
|
+
const rest = Buffer.from(`${path}\0${coowner.toString()}`, 'utf-8')
|
|
23
|
+
const instructionData = Buffer.concat([
|
|
24
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
25
|
+
Buffer.from(Int8Array.from([14]).buffer),
|
|
26
|
+
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
27
|
+
rest
|
|
28
|
+
])
|
|
29
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
30
|
+
const instruction = new TransactionInstruction({
|
|
31
|
+
keys: [
|
|
32
|
+
{
|
|
33
|
+
pubkey: wallet,
|
|
34
|
+
isSigner: true,
|
|
35
|
+
isWritable: true
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
pubkey: feeDistributorPda.pda,
|
|
39
|
+
isSigner: false,
|
|
40
|
+
isWritable: true
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
programId: new PublicKey(programId),
|
|
44
|
+
data: instructionData
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const tx = new Transaction().add(instruction)
|
|
48
|
+
return tx
|
|
49
|
+
}
|
package/src/bigbang.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
2
|
+
import BN from 'bn.js'
|
|
2
3
|
import { programId } from './const'
|
|
4
|
+
import { getFeeDistributorPda } from './helpers'
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Constructs a Solana transaction that triggers the "bigbang" instruction and create new file system.
|
|
6
8
|
*
|
|
7
9
|
* @param wallet - The public key of the wallet that will sign and authorize the transaction.
|
|
10
|
+
* @param replica_count - A stringified integer representing the number of replicas for the new file system. Must be 2 or greater. The total number of copies will be replica_count + 1 (one original plus the replicas).
|
|
8
11
|
* @returns A Promise that resolves to a Solana `Transaction` object containing the bigbang instruction.
|
|
9
12
|
*/
|
|
10
|
-
export async function bigbang
|
|
13
|
+
export async function bigbang(replica_count:string,wallet: PublicKey): Promise<Transaction> {
|
|
11
14
|
const instructionData = Buffer.concat([
|
|
12
|
-
Buffer.from(Int8Array.from([0]).buffer)
|
|
15
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
16
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
17
|
+
Buffer.from(Uint8Array.of(...new BN(replica_count).toArray('le', 8)))
|
|
13
18
|
])
|
|
19
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
14
20
|
|
|
15
21
|
const instruction = new TransactionInstruction({
|
|
16
22
|
keys: [
|
|
@@ -18,6 +24,11 @@ export async function bigbang (wallet: PublicKey): Promise<Transaction> {
|
|
|
18
24
|
pubkey: wallet,
|
|
19
25
|
isSigner: true,
|
|
20
26
|
isWritable: true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
pubkey: feeDistributorPda.pda,
|
|
30
|
+
isSigner: false,
|
|
31
|
+
isWritable: true
|
|
21
32
|
}
|
|
22
33
|
],
|
|
23
34
|
programId: new PublicKey(programId),
|
package/src/const.ts
CHANGED
package/src/copyPath.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
|
2
2
|
import BN from 'bn.js'
|
|
3
3
|
import { programId } from './const'
|
|
4
4
|
import { sanitizePath } from './sanitizePath'
|
|
5
|
+
import { getFeeDistributorPda } from './helpers.js'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Constructs a Solana transaction to copy a file or directory from one path to another.
|
|
@@ -29,17 +30,23 @@ export async function copyPath (
|
|
|
29
30
|
const rest = Buffer.from(`${srcPath}\0${destPath}`, 'utf-8')
|
|
30
31
|
|
|
31
32
|
const instructionData = Buffer.concat([
|
|
33
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
32
34
|
Buffer.from(Int8Array.from([9]).buffer),
|
|
33
35
|
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
34
36
|
rest
|
|
35
37
|
])
|
|
36
|
-
|
|
38
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
37
39
|
const instruction = new TransactionInstruction({
|
|
38
40
|
keys: [
|
|
39
41
|
{
|
|
40
42
|
pubkey: wallet,
|
|
41
43
|
isSigner: true,
|
|
42
44
|
isWritable: true
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
pubkey: feeDistributorPda.pda,
|
|
48
|
+
isSigner: false,
|
|
49
|
+
isWritable: true
|
|
43
50
|
}
|
|
44
51
|
],
|
|
45
52
|
programId: new PublicKey(programId),
|
package/src/createDirectory.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
|
2
2
|
import BN from 'bn.js'
|
|
3
3
|
import { programId } from './const'
|
|
4
4
|
import { sanitizePath } from './sanitizePath'
|
|
5
|
+
import { getFeeDistributorPda } from './helpers.js'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Constructs a Solana transaction to create a new directory within a file system.
|
|
@@ -21,21 +22,27 @@ export async function createDirectory (
|
|
|
21
22
|
wallet: PublicKey
|
|
22
23
|
): Promise<Transaction> {
|
|
23
24
|
// Validate path: only letters, numbers, and /
|
|
24
|
-
|
|
25
|
+
const combinedPath = path.endsWith('/') ? `${path}${name}` : `${path}/${name}`
|
|
25
26
|
sanitizePath(combinedPath)
|
|
26
27
|
const rest = Buffer.from(`${path}\0${name}`, 'utf-8')
|
|
27
28
|
const instructionData = Buffer.concat([
|
|
29
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
28
30
|
Buffer.from(Int8Array.from([6]).buffer),
|
|
29
31
|
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
30
32
|
rest
|
|
31
33
|
])
|
|
32
|
-
|
|
34
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
33
35
|
const instruction = new TransactionInstruction({
|
|
34
36
|
keys: [
|
|
35
37
|
{
|
|
36
38
|
pubkey: wallet,
|
|
37
39
|
isSigner: true,
|
|
38
40
|
isWritable: true
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
pubkey: feeDistributorPda.pda,
|
|
44
|
+
isSigner: false,
|
|
45
|
+
isWritable: true
|
|
39
46
|
}
|
|
40
47
|
],
|
|
41
48
|
programId: new PublicKey(programId),
|
package/src/createFile.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
|
2
2
|
import BN from 'bn.js'
|
|
3
3
|
import { programId } from './const'
|
|
4
4
|
import { sanitizePath } from './sanitizePath'
|
|
5
|
-
|
|
5
|
+
import { getFeeDistributorPda } from './helpers.js'
|
|
6
6
|
/**
|
|
7
7
|
* Constructs a Solana transaction to create a new file
|
|
8
8
|
* within a file system, identified by a file system ID (`fsid`).
|
|
@@ -20,22 +20,28 @@ export async function createFile (
|
|
|
20
20
|
name: string,
|
|
21
21
|
wallet: PublicKey
|
|
22
22
|
): Promise<Transaction> {
|
|
23
|
-
|
|
23
|
+
const combinedPath = path.endsWith('/') ? `${path}${name}` : `${path}/${name}`
|
|
24
24
|
sanitizePath(combinedPath);
|
|
25
25
|
|
|
26
26
|
const rest = Buffer.from(`${path}\0${name}`, 'utf-8')
|
|
27
27
|
const instructionData = Buffer.concat([
|
|
28
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
28
29
|
Buffer.from(Int8Array.from([2]).buffer),
|
|
29
30
|
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
30
31
|
rest
|
|
31
32
|
])
|
|
32
|
-
|
|
33
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
33
34
|
const instruction = new TransactionInstruction({
|
|
34
35
|
keys: [
|
|
35
36
|
{
|
|
36
37
|
pubkey: wallet,
|
|
37
38
|
isSigner: true,
|
|
38
39
|
isWritable: true
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
pubkey: feeDistributorPda.pda,
|
|
43
|
+
isSigner: false,
|
|
44
|
+
isWritable: true
|
|
39
45
|
}
|
|
40
46
|
],
|
|
41
47
|
programId: new PublicKey(programId),
|
package/src/exists.ts
CHANGED
|
@@ -38,7 +38,8 @@ export interface RpcRequest {
|
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
if (!response.ok) {
|
|
41
|
-
|
|
41
|
+
const errorText = await response.text();
|
|
42
|
+
return Error(`error! status: ${response.status}, message: ${errorText}`);
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
const data = await response.json()
|
package/src/find.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Connection } from "@solana/web3.js"
|
|
2
|
+
|
|
3
|
+
export interface RpcRequest {
|
|
4
|
+
jsonrpc: string
|
|
5
|
+
id: number
|
|
6
|
+
method: string
|
|
7
|
+
params: any[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Sends a JSON-RPC request to the Xandeum RPC endpoint to search for a file or directory
|
|
12
|
+
* within a specified path.
|
|
13
|
+
*
|
|
14
|
+
* This function calls the custom RPC method `find`, which is return an array of
|
|
15
|
+
* directory entry metadata — names, types etc.
|
|
16
|
+
*
|
|
17
|
+
* @param connection - The solana web3 connection with Xandeum-compatible JSON-RPC endpoint (e.g., `'https://api.devnet.solana.com'`).
|
|
18
|
+
* @param path - The filesystem path where the search will be performed (e.g., `/documents`).
|
|
19
|
+
* @param query - The query to search for (e.g., `'myfile.txt'`).
|
|
20
|
+
*
|
|
21
|
+
* @returns A `Promise<any>` resolving to the parsed JSON response from the RPC server,
|
|
22
|
+
* typically including a `result` array containing directory entry objects.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export async function find (
|
|
26
|
+
connection: Connection,
|
|
27
|
+
path: string,
|
|
28
|
+
query: string,
|
|
29
|
+
): Promise<any> {
|
|
30
|
+
const url = connection.rpcEndpoint;
|
|
31
|
+
const requestBody: RpcRequest = {
|
|
32
|
+
jsonrpc: '2.0',
|
|
33
|
+
id: 1,
|
|
34
|
+
method: 'find',
|
|
35
|
+
params: [path,query]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const response = await fetch(url, {
|
|
39
|
+
method: 'POST',
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json'
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify(requestBody)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
const errorText = await response.text();
|
|
48
|
+
return Error(`error! status: ${response.status}, message: ${errorText}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const data = await response.json()
|
|
52
|
+
return data
|
|
53
|
+
}
|
package/src/getMetadata.ts
CHANGED
|
@@ -41,7 +41,8 @@ export async function getMetadata (connection: Connection,path: string): Promise
|
|
|
41
41
|
})
|
|
42
42
|
|
|
43
43
|
if (!response.ok) {
|
|
44
|
-
|
|
44
|
+
const errorText = await response.text();
|
|
45
|
+
return Error(`error! status: ${response.status}, message: ${errorText}`);
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
const data = await response.json()
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
|
|
2
|
+
import { Connection } from "@solana/web3.js"
|
|
3
|
+
|
|
4
|
+
function sleep(ms: number) {
|
|
5
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Sends a JSON-RPC request to the Xandeum-compatible endpoint to retrieve
|
|
10
|
+
* the result of a transaction previously submitted with a specific signature.
|
|
11
|
+
*
|
|
12
|
+
* This function calls the custom RPC method `getXandeumResult`, which returns
|
|
13
|
+
* the result associated with the given transaction signature.
|
|
14
|
+
*
|
|
15
|
+
* @param connection - The Solana web3 connection object pointing to a Xandeum-compatible RPC endpoint.
|
|
16
|
+
* @param signature - The transaction signature string whose result should be queried.
|
|
17
|
+
*
|
|
18
|
+
* @returns A `Promise<any>` resolving to the parsed JSON response from the RPC server,
|
|
19
|
+
* which includes the result of the transaction if available.
|
|
20
|
+
*/
|
|
21
|
+
export async function getXandeumResult(
|
|
22
|
+
connection: Connection,
|
|
23
|
+
signature: string
|
|
24
|
+
): Promise<any> {
|
|
25
|
+
const url = connection.rpcEndpoint;
|
|
26
|
+
const maxAttempts = 3;
|
|
27
|
+
const delayMs = 5000;
|
|
28
|
+
|
|
29
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
30
|
+
// Wait before every attempt (including the first one)
|
|
31
|
+
await sleep(delayMs);
|
|
32
|
+
|
|
33
|
+
const response = await fetch(url, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: { "Content-Type": "application/json" },
|
|
36
|
+
body: JSON.stringify({
|
|
37
|
+
jsonrpc: "2.0",
|
|
38
|
+
id: 1,
|
|
39
|
+
method: "getXandeumResult",
|
|
40
|
+
params: [signature],
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const text = await response.text();
|
|
46
|
+
console.error(`Attempt ${attempt}/${maxAttempts} failed: ${response.status} ${text}`);
|
|
47
|
+
if (attempt === maxAttempts) {
|
|
48
|
+
return { result: null, error: `HTTP ${response.status}` };
|
|
49
|
+
}
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const data = await response.json();
|
|
54
|
+
|
|
55
|
+
// Change this condition if Xandeum uses a different "not ready" value
|
|
56
|
+
if (data?.result != null && data.result !== "pending") {
|
|
57
|
+
console.log(`Got result on attempt ${attempt}`);
|
|
58
|
+
return data; // Success — return immediately
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.log(`Attempt ${attempt}/${maxAttempts}: still pending...`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// All 3 attempts done, still no result
|
|
65
|
+
console.log("Max attempts reached — result still not available");
|
|
66
|
+
return { result: null, error: "Result not ready after 3 attempts" };
|
|
67
|
+
}
|
package/src/helpers.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js'
|
|
2
|
+
import { stoincProgramId } from './const'
|
|
3
|
+
import BN from 'bn.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Seed used for deriving the fee distributor PDA
|
|
7
|
+
*/
|
|
8
|
+
export const FEE_DISTRIBUTOR_SEED = 'fee_distributor'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Duration of one pulse in seconds
|
|
12
|
+
*/
|
|
13
|
+
export const PULSE_DURATION_SECONDS = 15
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Number of pulses in one yuga
|
|
17
|
+
*/
|
|
18
|
+
export const PULSES_PER_YUGA = 16384
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Duration of one yuga in seconds (16384 * 15 = 245,760 seconds ≈ 2.84 days)
|
|
22
|
+
*/
|
|
23
|
+
export const YUGA_DURATION_SECONDS = PULSES_PER_YUGA * PULSE_DURATION_SECONDS
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Unix timestamp (in seconds) when the first yuga started
|
|
27
|
+
*/
|
|
28
|
+
export const YUGA_START_TIMESTAMP = 1768898445
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Calculates the yuga number from a given unix timestamp.
|
|
32
|
+
*
|
|
33
|
+
* @param unixTimestamp - Unix timestamp in seconds
|
|
34
|
+
* @returns The yuga number for the given timestamp
|
|
35
|
+
*/
|
|
36
|
+
export function getYugaFromTimestamp(unixTimestamp: number): number {
|
|
37
|
+
if (unixTimestamp < YUGA_START_TIMESTAMP) {
|
|
38
|
+
return 0
|
|
39
|
+
}
|
|
40
|
+
return Math.floor((unixTimestamp - YUGA_START_TIMESTAMP) / YUGA_DURATION_SECONDS)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Gets the current yuga value.
|
|
45
|
+
* Yuga represents an epoch or era in the Xandeum system.
|
|
46
|
+
* Each yuga lasts 245,760 seconds (approximately 2.84 days).
|
|
47
|
+
*
|
|
48
|
+
* @returns The current yuga number
|
|
49
|
+
*/
|
|
50
|
+
export function getCurrentYuga(): number {
|
|
51
|
+
const currentTime = Math.floor(Date.now() / 1000)
|
|
52
|
+
return getYugaFromTimestamp(currentTime)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Derives the Program Derived Address (PDA) for the fee distributor account.
|
|
57
|
+
*
|
|
58
|
+
* The PDA is derived using:
|
|
59
|
+
* - The fee distributor seed
|
|
60
|
+
* - The current yuga (epoch) as little-endian bytes
|
|
61
|
+
*
|
|
62
|
+
* @returns An object containing the PDA public key and bump seed
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const { pda, bump } = getFeeDistributorPda()
|
|
67
|
+
* console.log('Fee Distributor PDA:', pda.toBase58())
|
|
68
|
+
* console.log('Bump seed:', bump)
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export function getFeeDistributorPda(): { pda: PublicKey; bump: number } {
|
|
72
|
+
const yuga = getCurrentYuga()
|
|
73
|
+
|
|
74
|
+
const yugaBuffer = Buffer.from(new BN(yuga).toArray('le', 8))
|
|
75
|
+
|
|
76
|
+
const [pda, bump] = PublicKey.findProgramAddressSync(
|
|
77
|
+
[
|
|
78
|
+
Buffer.from(FEE_DISTRIBUTOR_SEED, 'utf-8'),
|
|
79
|
+
yugaBuffer
|
|
80
|
+
],
|
|
81
|
+
new PublicKey(stoincProgramId)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
return { pda, bump }
|
|
85
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -9,7 +9,11 @@ export * from "./peek";
|
|
|
9
9
|
export * from "./poke";
|
|
10
10
|
export * from "./removeDirectory";
|
|
11
11
|
export * from "./copyPath";
|
|
12
|
-
|
|
12
|
+
export * from "./move";
|
|
13
|
+
export * from "./getXandeumResult";
|
|
14
|
+
export * from "./assignCoowner";
|
|
13
15
|
export {exists } from "./exists";
|
|
14
16
|
export {listDirectoryEntry} from "./listDirectoryEntery";
|
|
15
17
|
export {getMetadata} from "./getMetadata";
|
|
18
|
+
export {find} from "./find";
|
|
19
|
+
export * from "./helpers";
|
|
@@ -42,7 +42,8 @@ export async function listDirectoryEntry (
|
|
|
42
42
|
})
|
|
43
43
|
|
|
44
44
|
if (!response.ok) {
|
|
45
|
-
|
|
45
|
+
const errorText = await response.text();
|
|
46
|
+
return Error(`error! status: ${response.status}, message: ${errorText}`);
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
const data = await response.json()
|
package/src/move.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
2
|
+
import BN from 'bn.js'
|
|
3
|
+
import { programId } from './const'
|
|
4
|
+
import { sanitizePath } from './sanitizePath'
|
|
5
|
+
import { getFeeDistributorPda } from './helpers'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Constructs a Solana transaction to copy a file or directory from one path to another.
|
|
9
|
+
*
|
|
10
|
+
* @param fsid - The unique numeric identifier representing the target file system.
|
|
11
|
+
* @param srcPath - The source path to copy from (e.g., `/documents`).
|
|
12
|
+
* @param destPath - The destination path to copy to (e.g., `/archive`).
|
|
13
|
+
* @param name - The name of the new file or directory at the destination (e.g., `report.txt`).
|
|
14
|
+
* @param wallet - The wallet public key used to sign and authorize the transaction.
|
|
15
|
+
* @returns A Promise that resolves to a Solana `Transaction` object containing the copyPath instruction.
|
|
16
|
+
* @throws Will throw an error if `srcPath` or `destPath` contains invalid characters.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export async function move (
|
|
21
|
+
fsid: string,
|
|
22
|
+
srcPath: string,
|
|
23
|
+
destPath: string,
|
|
24
|
+
name: string,
|
|
25
|
+
wallet: PublicKey
|
|
26
|
+
): Promise<Transaction> {
|
|
27
|
+
// Validate path: only letters, numbers, and /
|
|
28
|
+
sanitizePath(srcPath)
|
|
29
|
+
|
|
30
|
+
sanitizePath(destPath)
|
|
31
|
+
sanitizePath(name)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
const rest = Buffer.from(`${srcPath}\0${destPath}\0${name}`, 'utf-8')
|
|
35
|
+
|
|
36
|
+
const instructionData = Buffer.concat([
|
|
37
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
38
|
+
Buffer.from(Int8Array.from([13]).buffer),
|
|
39
|
+
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
40
|
+
rest
|
|
41
|
+
])
|
|
42
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
43
|
+
const instruction = new TransactionInstruction({
|
|
44
|
+
keys: [
|
|
45
|
+
{
|
|
46
|
+
pubkey: wallet,
|
|
47
|
+
isSigner: true,
|
|
48
|
+
isWritable: true
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
pubkey: feeDistributorPda.pda,
|
|
52
|
+
isSigner: false,
|
|
53
|
+
isWritable: true
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
programId: new PublicKey(programId),
|
|
57
|
+
data: instructionData
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const tx = new Transaction().add(instruction)
|
|
61
|
+
return tx
|
|
62
|
+
}
|
package/src/peek.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
|
2
2
|
import BN from 'bn.js'
|
|
3
3
|
import { programId } from './const'
|
|
4
4
|
import { sanitizePath } from './sanitizePath'
|
|
5
|
+
import { getFeeDistributorPda } from './helpers'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Constructs a Solana transaction to perform a "peek" operation on a file within a file system.
|
|
@@ -28,19 +29,25 @@ export async function peek (
|
|
|
28
29
|
|
|
29
30
|
const rest = Buffer.from(`${path}`, 'utf-8')
|
|
30
31
|
const instructionData = Buffer.concat([
|
|
32
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
31
33
|
Buffer.from(Int8Array.from([3]).buffer),
|
|
32
34
|
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
33
35
|
Buffer.from(Uint8Array.of(...new BN(startPosition).toArray('le', 8))),
|
|
34
36
|
Buffer.from(Uint8Array.of(...new BN(endPosition).toArray('le', 8))),
|
|
35
37
|
rest
|
|
36
38
|
])
|
|
37
|
-
|
|
39
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
38
40
|
const instruction = new TransactionInstruction({
|
|
39
41
|
keys: [
|
|
40
42
|
{
|
|
41
43
|
pubkey: wallet,
|
|
42
44
|
isSigner: true,
|
|
43
45
|
isWritable: true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
pubkey: feeDistributorPda.pda,
|
|
49
|
+
isSigner: false,
|
|
50
|
+
isWritable: true
|
|
44
51
|
}
|
|
45
52
|
],
|
|
46
53
|
programId: new PublicKey(programId),
|
package/src/poke.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
|
2
2
|
import BN from 'bn.js'
|
|
3
3
|
import { programId } from './const'
|
|
4
4
|
import { sanitizePath } from './sanitizePath'
|
|
5
|
+
import { getFeeDistributorPda } from './helpers'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Constructs a Solana transaction to perform a poke\operation, which writes data
|
|
@@ -30,13 +31,14 @@ export async function poke (
|
|
|
30
31
|
// Encode the path length as an 8-byte little-endian unsigned integer
|
|
31
32
|
const pathLengthBuffer = Buffer.from(Uint8Array.of(...new BN(pathBuffer.length).toArray('le', 8)))
|
|
32
33
|
const instructionData = Buffer.concat([
|
|
34
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
33
35
|
Buffer.from(Int8Array.from([4]).buffer),
|
|
34
36
|
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
35
37
|
Buffer.from(Uint8Array.of(...new BN(position).toArray('le', 8))),
|
|
36
38
|
pathLengthBuffer,
|
|
37
39
|
pathBuffer
|
|
38
40
|
])
|
|
39
|
-
|
|
41
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
40
42
|
const instruction = new TransactionInstruction({
|
|
41
43
|
keys: [
|
|
42
44
|
{
|
|
@@ -48,6 +50,11 @@ export async function poke (
|
|
|
48
50
|
pubkey: dataKey,
|
|
49
51
|
isSigner: false,
|
|
50
52
|
isWritable: false
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
pubkey: feeDistributorPda.pda,
|
|
56
|
+
isSigner: false,
|
|
57
|
+
isWritable: true
|
|
51
58
|
}
|
|
52
59
|
],
|
|
53
60
|
programId: new PublicKey(programId),
|
package/src/removeDirectory.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
|
2
2
|
import BN from 'bn.js'
|
|
3
3
|
import { programId } from './const'
|
|
4
4
|
import { sanitizePath } from './sanitizePath'
|
|
5
|
-
|
|
5
|
+
import { getFeeDistributorPda } from './helpers'
|
|
6
6
|
/**
|
|
7
7
|
* Constructs a Solana transaction to perform a "remove directory" operation
|
|
8
8
|
* in a file system, identified by a file system ID (`fsid`).
|
|
@@ -21,17 +21,23 @@ export async function removeDirectory (
|
|
|
21
21
|
): Promise<Transaction> {
|
|
22
22
|
sanitizePath(path)
|
|
23
23
|
const instructionData = Buffer.concat([
|
|
24
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
24
25
|
Buffer.from(Int8Array.from([7]).buffer),
|
|
25
26
|
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
26
27
|
Buffer.from(`${path}`, 'utf-8')
|
|
27
28
|
])
|
|
28
|
-
|
|
29
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
29
30
|
const instruction = new TransactionInstruction({
|
|
30
31
|
keys: [
|
|
31
32
|
{
|
|
32
33
|
pubkey: wallet,
|
|
33
34
|
isSigner: true,
|
|
34
35
|
isWritable: true
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
pubkey: feeDistributorPda.pda,
|
|
39
|
+
isSigner: false,
|
|
40
|
+
isWritable: true
|
|
35
41
|
}
|
|
36
42
|
],
|
|
37
43
|
programId: new PublicKey(programId),
|
package/src/removeFile.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Transaction, TransactionInstruction, PublicKey } from '@solana/web3.js'
|
|
|
2
2
|
import BN from 'bn.js'
|
|
3
3
|
import { programId } from './const'
|
|
4
4
|
import { sanitizePath } from './sanitizePath'
|
|
5
|
-
|
|
5
|
+
import { getFeeDistributorPda } from './helpers'
|
|
6
6
|
/**
|
|
7
7
|
* Constructs a Solana transaction to remove a file from a file system,
|
|
8
8
|
* identified by a file system ID (`fsid`) and a UTF-8 encoded file path.
|
|
@@ -22,17 +22,23 @@ export async function removeFile (
|
|
|
22
22
|
sanitizePath(path)
|
|
23
23
|
|
|
24
24
|
const instructionData = Buffer.concat([
|
|
25
|
+
Buffer.from(Int8Array.from([0]).buffer),
|
|
25
26
|
Buffer.from(Int8Array.from([5]).buffer),
|
|
26
27
|
Buffer.from(Uint8Array.of(...new BN(fsid).toArray('le', 8))),
|
|
27
28
|
Buffer.from(`${path}`, 'utf-8')
|
|
28
29
|
])
|
|
29
|
-
|
|
30
|
+
let feeDistributorPda = getFeeDistributorPda()
|
|
30
31
|
const instruction = new TransactionInstruction({
|
|
31
32
|
keys: [
|
|
32
33
|
{
|
|
33
34
|
pubkey: wallet,
|
|
34
35
|
isSigner: true,
|
|
35
36
|
isWritable: true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
pubkey: feeDistributorPda.pda,
|
|
40
|
+
isSigner: false,
|
|
41
|
+
isWritable: true
|
|
36
42
|
}
|
|
37
43
|
],
|
|
38
44
|
programId: new PublicKey(programId),
|