@talismn/solana 0.0.0 → 0.0.2

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 +1,4 @@
1
- export * from "./utils";
1
+ export * from "./utils/serialization";
2
+ export * from "./utils/signing";
3
+ export * from "./utils/chains";
4
+ export * from "./utils/transaction";
@@ -0,0 +1,3 @@
1
+ export declare const SOLANA_CHAINS: readonly ["solana:mainnet", "solana:devnet", "solana:testnet", "solana:localnet"];
2
+ export type SolanaChainId = (typeof SOLANA_CHAINS)[number];
3
+ export declare const getSolNetworkId: (chain: SolanaChainId) => "solana-mainnet" | "solana-devnet" | "solana-testnet" | "solana-localnet";
@@ -1,12 +1,17 @@
1
- import { TransactionInstruction } from "@solana/web3.js";
2
- export declare const serializeInstruction: (instruction: TransactionInstruction) => {
3
- programId: string;
4
- keys: {
5
- pubkey: string;
6
- isSigner: boolean;
7
- isWritable: boolean;
8
- }[];
9
- data: string;
1
+ import { Transaction, TransactionInstruction, VersionedTransaction } from "@solana/web3.js";
2
+ export declare const solInstructionToJson: (instruction: TransactionInstruction) => {
3
+ type: "solana-instruction";
4
+ value: {
5
+ programId: string;
6
+ keys: {
7
+ pubkey: string;
8
+ isSigner: boolean;
9
+ isWritable: boolean;
10
+ }[];
11
+ data: string;
12
+ };
10
13
  };
11
- export type SerializedInstruction = ReturnType<typeof serializeInstruction>;
12
- export declare const deserializeInstruction: (serialized: SerializedInstruction) => TransactionInstruction;
14
+ export type SolInstructionJson = ReturnType<typeof solInstructionToJson>;
15
+ export declare const solInstructionFromJson: (serialized: SolInstructionJson) => TransactionInstruction;
16
+ export declare const serializeTransaction: (transaction: Transaction | VersionedTransaction) => string;
17
+ export declare const deserializeTransaction: (transaction: string) => Transaction | VersionedTransaction;
@@ -0,0 +1,2 @@
1
+ import { Keypair } from "@solana/web3.js";
2
+ export declare const getKeypair: (secretKey: Uint8Array) => Keypair;
@@ -0,0 +1,7 @@
1
+ import { Transaction, VersionedTransaction } from "@solana/web3.js";
2
+ export declare const isVersionedTransaction: (transaction: Transaction | VersionedTransaction) => transaction is VersionedTransaction;
3
+ export declare const parseTransactionInfo: (tx: Transaction | VersionedTransaction) => {
4
+ recentBlockhash: string | undefined;
5
+ address: string | undefined;
6
+ signature: string | null;
7
+ };
@@ -1,31 +1,112 @@
1
1
  'use strict';
2
2
 
3
3
  var web3_js = require('@solana/web3.js');
4
+ var crypto = require('@talismn/crypto');
5
+
6
+ const isVersionedTransaction = transaction => {
7
+ return "version" in transaction;
8
+ };
9
+ const parseTransactionInfo = tx => {
10
+ if (isVersionedTransaction(tx)) {
11
+ const recentBlockhash = tx.message.recentBlockhash;
12
+ const requiredSigners = tx.message.staticAccountKeys.filter((_, index) => tx.message.isAccountSigner(index));
13
+ const address = requiredSigners.length === 1 ? requiredSigners[0].toBase58() : undefined;
14
+ const sigBytes = tx.signatures.length ? tx.signatures[0] : null;
15
+
16
+ // signature might be an array of zeros, signature needs to be verified manually
17
+ const signature = sigBytes && address && crypto.ed25519.verify(sigBytes, tx.message.serialize(), crypto.base58.decode(address)) ? crypto.base58.encode(sigBytes) : null;
18
+ return {
19
+ recentBlockhash,
20
+ address,
21
+ signature
22
+ };
23
+ } else {
24
+ const recentBlockhash = tx.recentBlockhash;
25
+ const address = tx.feePayer ? tx.feePayer.toBase58() : undefined;
26
+ const signature = tx.verifySignatures() ? crypto.base58.encode(tx.signature) : null;
27
+ return {
28
+ recentBlockhash,
29
+ address,
30
+ signature
31
+ };
32
+ }
33
+ };
4
34
 
5
35
  // Serialize TransactionInstruction to JSON
6
- const serializeInstruction = instruction => {
36
+ const solInstructionToJson = instruction => {
7
37
  return {
8
- programId: instruction.programId.toString(),
9
- keys: instruction.keys.map(key => ({
10
- pubkey: key.pubkey.toString(),
11
- isSigner: key.isSigner,
12
- isWritable: key.isWritable
13
- })),
14
- data: instruction.data.toString("base64")
38
+ type: "solana-instruction",
39
+ value: {
40
+ programId: instruction.programId.toString(),
41
+ keys: instruction.keys.map(key => ({
42
+ pubkey: key.pubkey.toString(),
43
+ isSigner: key.isSigner,
44
+ isWritable: key.isWritable
45
+ })),
46
+ data: instruction.data.toString("base64")
47
+ }
15
48
  };
16
49
  };
17
50
  // Deserialize JSON back to TransactionInstruction
18
- const deserializeInstruction = serialized => {
51
+ const solInstructionFromJson = serialized => {
52
+ if (serialized.type !== "solana-instruction") throw new Error("Invalid serialized instruction type");
19
53
  return {
20
- programId: new web3_js.PublicKey(serialized.programId),
21
- keys: serialized.keys.map(key => ({
54
+ programId: new web3_js.PublicKey(serialized.value.programId),
55
+ keys: serialized.value.keys.map(key => ({
22
56
  pubkey: new web3_js.PublicKey(key.pubkey),
23
57
  isSigner: key.isSigner,
24
58
  isWritable: key.isWritable
25
59
  })),
26
- data: Buffer.from(serialized.data, "base64")
60
+ data: Buffer.from(serialized.value.data, "base64")
27
61
  };
28
62
  };
63
+ const serializeTransaction = transaction => {
64
+ if (isVersionedTransaction(transaction)) {
65
+ return crypto.base58.encode(transaction.serialize());
66
+ } else {
67
+ return crypto.base58.encode(transaction.serialize({
68
+ requireAllSignatures: false,
69
+ verifySignatures: false
70
+ }));
71
+ }
72
+ };
73
+ const deserializeTransaction = transaction => {
74
+ const bytes = crypto.base58.decode(transaction);
75
+ try {
76
+ return web3_js.VersionedTransaction.deserialize(bytes);
77
+ } catch {
78
+ return web3_js.Transaction.from(bytes);
79
+ }
80
+ };
81
+
82
+ const getKeypair = secretKey => {
83
+ const publicKey = crypto.getPublicKeyFromSecret(secretKey, "solana");
84
+ const fullScretKey = new Uint8Array([...secretKey, ...publicKey]);
85
+ return web3_js.Keypair.fromSecretKey(fullScretKey);
86
+ };
87
+
88
+ const SOLANA_CHAINS = ["solana:mainnet", "solana:devnet", "solana:testnet", "solana:localnet"];
89
+ const getSolNetworkId = chain => {
90
+ switch (chain) {
91
+ case "solana:mainnet":
92
+ return "solana-mainnet";
93
+ case "solana:devnet":
94
+ return "solana-devnet";
95
+ case "solana:testnet":
96
+ return "solana-testnet";
97
+ case "solana:localnet":
98
+ return "solana-localnet";
99
+ default:
100
+ throw new Error(`Unknown Solana chain: ${chain}`);
101
+ }
102
+ };
29
103
 
30
- exports.deserializeInstruction = deserializeInstruction;
31
- exports.serializeInstruction = serializeInstruction;
104
+ exports.SOLANA_CHAINS = SOLANA_CHAINS;
105
+ exports.deserializeTransaction = deserializeTransaction;
106
+ exports.getKeypair = getKeypair;
107
+ exports.getSolNetworkId = getSolNetworkId;
108
+ exports.isVersionedTransaction = isVersionedTransaction;
109
+ exports.parseTransactionInfo = parseTransactionInfo;
110
+ exports.serializeTransaction = serializeTransaction;
111
+ exports.solInstructionFromJson = solInstructionFromJson;
112
+ exports.solInstructionToJson = solInstructionToJson;
@@ -1,31 +1,112 @@
1
1
  'use strict';
2
2
 
3
3
  var web3_js = require('@solana/web3.js');
4
+ var crypto = require('@talismn/crypto');
5
+
6
+ const isVersionedTransaction = transaction => {
7
+ return "version" in transaction;
8
+ };
9
+ const parseTransactionInfo = tx => {
10
+ if (isVersionedTransaction(tx)) {
11
+ const recentBlockhash = tx.message.recentBlockhash;
12
+ const requiredSigners = tx.message.staticAccountKeys.filter((_, index) => tx.message.isAccountSigner(index));
13
+ const address = requiredSigners.length === 1 ? requiredSigners[0].toBase58() : undefined;
14
+ const sigBytes = tx.signatures.length ? tx.signatures[0] : null;
15
+
16
+ // signature might be an array of zeros, signature needs to be verified manually
17
+ const signature = sigBytes && address && crypto.ed25519.verify(sigBytes, tx.message.serialize(), crypto.base58.decode(address)) ? crypto.base58.encode(sigBytes) : null;
18
+ return {
19
+ recentBlockhash,
20
+ address,
21
+ signature
22
+ };
23
+ } else {
24
+ const recentBlockhash = tx.recentBlockhash;
25
+ const address = tx.feePayer ? tx.feePayer.toBase58() : undefined;
26
+ const signature = tx.verifySignatures() ? crypto.base58.encode(tx.signature) : null;
27
+ return {
28
+ recentBlockhash,
29
+ address,
30
+ signature
31
+ };
32
+ }
33
+ };
4
34
 
5
35
  // Serialize TransactionInstruction to JSON
6
- const serializeInstruction = instruction => {
36
+ const solInstructionToJson = instruction => {
7
37
  return {
8
- programId: instruction.programId.toString(),
9
- keys: instruction.keys.map(key => ({
10
- pubkey: key.pubkey.toString(),
11
- isSigner: key.isSigner,
12
- isWritable: key.isWritable
13
- })),
14
- data: instruction.data.toString("base64")
38
+ type: "solana-instruction",
39
+ value: {
40
+ programId: instruction.programId.toString(),
41
+ keys: instruction.keys.map(key => ({
42
+ pubkey: key.pubkey.toString(),
43
+ isSigner: key.isSigner,
44
+ isWritable: key.isWritable
45
+ })),
46
+ data: instruction.data.toString("base64")
47
+ }
15
48
  };
16
49
  };
17
50
  // Deserialize JSON back to TransactionInstruction
18
- const deserializeInstruction = serialized => {
51
+ const solInstructionFromJson = serialized => {
52
+ if (serialized.type !== "solana-instruction") throw new Error("Invalid serialized instruction type");
19
53
  return {
20
- programId: new web3_js.PublicKey(serialized.programId),
21
- keys: serialized.keys.map(key => ({
54
+ programId: new web3_js.PublicKey(serialized.value.programId),
55
+ keys: serialized.value.keys.map(key => ({
22
56
  pubkey: new web3_js.PublicKey(key.pubkey),
23
57
  isSigner: key.isSigner,
24
58
  isWritable: key.isWritable
25
59
  })),
26
- data: Buffer.from(serialized.data, "base64")
60
+ data: Buffer.from(serialized.value.data, "base64")
27
61
  };
28
62
  };
63
+ const serializeTransaction = transaction => {
64
+ if (isVersionedTransaction(transaction)) {
65
+ return crypto.base58.encode(transaction.serialize());
66
+ } else {
67
+ return crypto.base58.encode(transaction.serialize({
68
+ requireAllSignatures: false,
69
+ verifySignatures: false
70
+ }));
71
+ }
72
+ };
73
+ const deserializeTransaction = transaction => {
74
+ const bytes = crypto.base58.decode(transaction);
75
+ try {
76
+ return web3_js.VersionedTransaction.deserialize(bytes);
77
+ } catch {
78
+ return web3_js.Transaction.from(bytes);
79
+ }
80
+ };
81
+
82
+ const getKeypair = secretKey => {
83
+ const publicKey = crypto.getPublicKeyFromSecret(secretKey, "solana");
84
+ const fullScretKey = new Uint8Array([...secretKey, ...publicKey]);
85
+ return web3_js.Keypair.fromSecretKey(fullScretKey);
86
+ };
87
+
88
+ const SOLANA_CHAINS = ["solana:mainnet", "solana:devnet", "solana:testnet", "solana:localnet"];
89
+ const getSolNetworkId = chain => {
90
+ switch (chain) {
91
+ case "solana:mainnet":
92
+ return "solana-mainnet";
93
+ case "solana:devnet":
94
+ return "solana-devnet";
95
+ case "solana:testnet":
96
+ return "solana-testnet";
97
+ case "solana:localnet":
98
+ return "solana-localnet";
99
+ default:
100
+ throw new Error(`Unknown Solana chain: ${chain}`);
101
+ }
102
+ };
29
103
 
30
- exports.deserializeInstruction = deserializeInstruction;
31
- exports.serializeInstruction = serializeInstruction;
104
+ exports.SOLANA_CHAINS = SOLANA_CHAINS;
105
+ exports.deserializeTransaction = deserializeTransaction;
106
+ exports.getKeypair = getKeypair;
107
+ exports.getSolNetworkId = getSolNetworkId;
108
+ exports.isVersionedTransaction = isVersionedTransaction;
109
+ exports.parseTransactionInfo = parseTransactionInfo;
110
+ exports.serializeTransaction = serializeTransaction;
111
+ exports.solInstructionFromJson = solInstructionFromJson;
112
+ exports.solInstructionToJson = solInstructionToJson;
@@ -1,28 +1,102 @@
1
- import { PublicKey } from '@solana/web3.js';
1
+ import { PublicKey, VersionedTransaction, Transaction, Keypair } from '@solana/web3.js';
2
+ import { ed25519, base58, getPublicKeyFromSecret } from '@talismn/crypto';
3
+
4
+ const isVersionedTransaction = transaction => {
5
+ return "version" in transaction;
6
+ };
7
+ const parseTransactionInfo = tx => {
8
+ if (isVersionedTransaction(tx)) {
9
+ const recentBlockhash = tx.message.recentBlockhash;
10
+ const requiredSigners = tx.message.staticAccountKeys.filter((_, index) => tx.message.isAccountSigner(index));
11
+ const address = requiredSigners.length === 1 ? requiredSigners[0].toBase58() : undefined;
12
+ const sigBytes = tx.signatures.length ? tx.signatures[0] : null;
13
+
14
+ // signature might be an array of zeros, signature needs to be verified manually
15
+ const signature = sigBytes && address && ed25519.verify(sigBytes, tx.message.serialize(), base58.decode(address)) ? base58.encode(sigBytes) : null;
16
+ return {
17
+ recentBlockhash,
18
+ address,
19
+ signature
20
+ };
21
+ } else {
22
+ const recentBlockhash = tx.recentBlockhash;
23
+ const address = tx.feePayer ? tx.feePayer.toBase58() : undefined;
24
+ const signature = tx.verifySignatures() ? base58.encode(tx.signature) : null;
25
+ return {
26
+ recentBlockhash,
27
+ address,
28
+ signature
29
+ };
30
+ }
31
+ };
2
32
 
3
33
  // Serialize TransactionInstruction to JSON
4
- const serializeInstruction = instruction => {
34
+ const solInstructionToJson = instruction => {
5
35
  return {
6
- programId: instruction.programId.toString(),
7
- keys: instruction.keys.map(key => ({
8
- pubkey: key.pubkey.toString(),
9
- isSigner: key.isSigner,
10
- isWritable: key.isWritable
11
- })),
12
- data: instruction.data.toString("base64")
36
+ type: "solana-instruction",
37
+ value: {
38
+ programId: instruction.programId.toString(),
39
+ keys: instruction.keys.map(key => ({
40
+ pubkey: key.pubkey.toString(),
41
+ isSigner: key.isSigner,
42
+ isWritable: key.isWritable
43
+ })),
44
+ data: instruction.data.toString("base64")
45
+ }
13
46
  };
14
47
  };
15
48
  // Deserialize JSON back to TransactionInstruction
16
- const deserializeInstruction = serialized => {
49
+ const solInstructionFromJson = serialized => {
50
+ if (serialized.type !== "solana-instruction") throw new Error("Invalid serialized instruction type");
17
51
  return {
18
- programId: new PublicKey(serialized.programId),
19
- keys: serialized.keys.map(key => ({
52
+ programId: new PublicKey(serialized.value.programId),
53
+ keys: serialized.value.keys.map(key => ({
20
54
  pubkey: new PublicKey(key.pubkey),
21
55
  isSigner: key.isSigner,
22
56
  isWritable: key.isWritable
23
57
  })),
24
- data: Buffer.from(serialized.data, "base64")
58
+ data: Buffer.from(serialized.value.data, "base64")
25
59
  };
26
60
  };
61
+ const serializeTransaction = transaction => {
62
+ if (isVersionedTransaction(transaction)) {
63
+ return base58.encode(transaction.serialize());
64
+ } else {
65
+ return base58.encode(transaction.serialize({
66
+ requireAllSignatures: false,
67
+ verifySignatures: false
68
+ }));
69
+ }
70
+ };
71
+ const deserializeTransaction = transaction => {
72
+ const bytes = base58.decode(transaction);
73
+ try {
74
+ return VersionedTransaction.deserialize(bytes);
75
+ } catch {
76
+ return Transaction.from(bytes);
77
+ }
78
+ };
79
+
80
+ const getKeypair = secretKey => {
81
+ const publicKey = getPublicKeyFromSecret(secretKey, "solana");
82
+ const fullScretKey = new Uint8Array([...secretKey, ...publicKey]);
83
+ return Keypair.fromSecretKey(fullScretKey);
84
+ };
85
+
86
+ const SOLANA_CHAINS = ["solana:mainnet", "solana:devnet", "solana:testnet", "solana:localnet"];
87
+ const getSolNetworkId = chain => {
88
+ switch (chain) {
89
+ case "solana:mainnet":
90
+ return "solana-mainnet";
91
+ case "solana:devnet":
92
+ return "solana-devnet";
93
+ case "solana:testnet":
94
+ return "solana-testnet";
95
+ case "solana:localnet":
96
+ return "solana-localnet";
97
+ default:
98
+ throw new Error(`Unknown Solana chain: ${chain}`);
99
+ }
100
+ };
27
101
 
28
- export { deserializeInstruction, serializeInstruction };
102
+ export { SOLANA_CHAINS, deserializeTransaction, getKeypair, getSolNetworkId, isVersionedTransaction, parseTransactionInfo, serializeTransaction, solInstructionFromJson, solInstructionToJson };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talismn/solana",
3
- "version": "0.0.0",
3
+ "version": "0.0.2",
4
4
  "author": "Talisman",
5
5
  "homepage": "https://talisman.xyz",
6
6
  "license": "GPL-3.0-or-later",
@@ -18,11 +18,12 @@
18
18
  "/dist"
19
19
  ],
20
20
  "engines": {
21
- "node": ">=18"
21
+ "node": ">=20"
22
22
  },
23
23
  "dependencies": {
24
24
  "@solana/web3.js": "^1.98.2",
25
- "anylogger": "^1.0.11"
25
+ "anylogger": "^1.0.11",
26
+ "@talismn/crypto": "0.2.2"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@types/jest": "^29.5.14",
@@ -1 +0,0 @@
1
- export * from "./serialization";