@exodus/solana-lib 1.6.6 → 1.6.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 +4 -4
- package/src/encode.js +11 -15
- package/src/helpers/spl-token.js +5 -14
- package/src/helpers/tokenTransfer.js +7 -7
- package/src/helpers/transaction-strategy.js +1 -1
- package/src/index.js +0 -2
- package/src/keypair.js +4 -9
- package/src/transaction.js +2 -3
- package/src/tx/build-raw-transaction.js +3 -3
- package/src/tx/create-and-sign-tx.js +1 -2
- package/src/tx/create-unsigned-tx.js +1 -3
- package/src/tx/decode-tx-instructions.js +22 -46
- package/src/tx/parse-unsigned-tx.js +1 -2
- package/src/tx/sign-unsigned-tx.js +1 -5
- package/src/tx/simulate-and-sign-tx.js +1 -1
- package/src/vendor/account.js +4 -6
- package/src/vendor/instruction.js +2 -10
- package/src/vendor/message.js +11 -29
- package/src/vendor/nonce-account.js +6 -7
- package/src/vendor/publickey.js +9 -14
- package/src/vendor/stake-program.js +22 -83
- package/src/vendor/system-program.js +25 -104
- package/src/vendor/sysvar.js +0 -1
- package/src/vendor/transaction.js +37 -70
- package/src/vendor/utils/blockhash.js +0 -3
- package/src/vendor/utils/fee-calculator.js +0 -4
- package/src/vendor/utils/layout.js +7 -8
- package/src/vendor/utils/shortvec-encoding.js +2 -4
- package/src/vendor/utils/to-buffer.js +1 -1
- package/src/versioned-transaction.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/solana-lib",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.8",
|
|
4
4
|
"description": "Exodus internal Solana low-level library",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"@exodus/asset-lib": "^3.7.1",
|
|
17
17
|
"@exodus/buffer-layout": "^1.2.0-exodus1",
|
|
18
18
|
"@exodus/key-utils": "^3.1.0",
|
|
19
|
-
"@exodus/models": "^
|
|
20
|
-
"@exodus/solana-meta": "^1.0.
|
|
19
|
+
"@exodus/models": "^10.1.0",
|
|
20
|
+
"@exodus/solana-meta": "^1.0.3",
|
|
21
21
|
"@exodus/solana-spl-token": "0.1.8-exodus.1",
|
|
22
22
|
"@project-serum/serum": "0.13.64",
|
|
23
23
|
"bn.js": "^4.11.0",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"lodash": "^4.17.11",
|
|
28
28
|
"tweetnacl": "^1.0.3"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "846ed76714355879216f43c6be8ec2b072169635"
|
|
31
31
|
}
|
package/src/encode.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import assert from 'assert'
|
|
3
2
|
import { PublicKey, StakeProgram } from './vendor'
|
|
4
3
|
import {
|
|
@@ -28,15 +27,15 @@ BinaryWriter.prototype.writePubkeyAsString = function (value) {
|
|
|
28
27
|
}
|
|
29
28
|
*/
|
|
30
29
|
|
|
31
|
-
export function getAddressFromPublicKey(publicKey
|
|
30
|
+
export function getAddressFromPublicKey(publicKey) {
|
|
32
31
|
return bs58.encode(Buffer.from(publicKey, 'hex'))
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
export function getAddressFromPrivateKey(privateKey
|
|
34
|
+
export function getAddressFromPrivateKey(privateKey) {
|
|
36
35
|
return getAddressFromPublicKey(getPublicKey(privateKey))
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
export function isValidAddress(address
|
|
38
|
+
export function isValidAddress(address) {
|
|
40
39
|
try {
|
|
41
40
|
// assume base 58 encoding by default
|
|
42
41
|
const decoded = bs58.decode(address)
|
|
@@ -53,22 +52,19 @@ export function isValidAddress(address: string): boolean {
|
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
export function getEncodedSecretKey(privateKey)
|
|
55
|
+
export function getEncodedSecretKey(privateKey) {
|
|
57
56
|
const { secretKey } = getKeyPairFromPrivateKey(Buffer.from(privateKey, 'hex'))
|
|
58
57
|
return bs58.encode(secretKey)
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
export function getPrivateKeyFromSecretKey(secretKey
|
|
60
|
+
export function getPrivateKeyFromSecretKey(secretKey) {
|
|
62
61
|
const privateKey = bs58.decode(secretKey).slice(0, 32) // Buffer
|
|
63
62
|
assert(privateKey.length === 32, 'privateKey has unexpected length')
|
|
64
63
|
return privateKey
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
// doc: https://spl.solana.com/associated-token-account (HACK: refactored to sync)
|
|
68
|
-
export function findAssociatedTokenAddress(
|
|
69
|
-
walletAddress: string,
|
|
70
|
-
tokenMintAddress: string
|
|
71
|
-
): string {
|
|
67
|
+
export function findAssociatedTokenAddress(walletAddress, tokenMintAddress) {
|
|
72
68
|
walletAddress = new PublicKey(walletAddress)
|
|
73
69
|
tokenMintAddress = new PublicKey(tokenMintAddress)
|
|
74
70
|
return PublicKey.findProgramAddress(
|
|
@@ -77,7 +73,7 @@ export function findAssociatedTokenAddress(
|
|
|
77
73
|
)[0].toBase58() // returns encoded PublicKey
|
|
78
74
|
}
|
|
79
75
|
|
|
80
|
-
export function createStakeAddress(walletAddress
|
|
76
|
+
export function createStakeAddress(walletAddress, seed = SEED) {
|
|
81
77
|
const fromPubkey = new PublicKey(walletAddress)
|
|
82
78
|
|
|
83
79
|
const newAccountPubkey = PublicKey.createWithSeed(
|
|
@@ -91,7 +87,7 @@ export function createStakeAddress(walletAddress: string, seed = SEED): string {
|
|
|
91
87
|
}
|
|
92
88
|
|
|
93
89
|
// get Metaplex Metadata account
|
|
94
|
-
export function getMetadataAccount(tokenMintAddress
|
|
90
|
+
export function getMetadataAccount(tokenMintAddress) {
|
|
95
91
|
const METADATA_PREFIX = 'metadata'
|
|
96
92
|
|
|
97
93
|
return PublicKey.findProgramAddress(
|
|
@@ -105,7 +101,7 @@ export function getMetadataAccount(tokenMintAddress: string): string {
|
|
|
105
101
|
}
|
|
106
102
|
|
|
107
103
|
// metaplex NFT Master Edition PDA
|
|
108
|
-
export function getMasterEditionPDA(tokenMintAddress
|
|
104
|
+
export function getMasterEditionPDA(tokenMintAddress) {
|
|
109
105
|
return PublicKey.findProgramAddress(
|
|
110
106
|
[
|
|
111
107
|
Buffer.from('metadata', 'utf8'),
|
|
@@ -118,7 +114,7 @@ export function getMasterEditionPDA(tokenMintAddress: string): string {
|
|
|
118
114
|
}
|
|
119
115
|
|
|
120
116
|
// metaplex TokenRecord PDA
|
|
121
|
-
export function getTokenRecordPDA(tokenMintAddress
|
|
117
|
+
export function getTokenRecordPDA(tokenMintAddress, token) {
|
|
122
118
|
return PublicKey.findProgramAddress(
|
|
123
119
|
[
|
|
124
120
|
Buffer.from('metadata', 'utf8'),
|
|
@@ -131,7 +127,7 @@ export function getTokenRecordPDA(tokenMintAddress: string, token: string): stri
|
|
|
131
127
|
)[0].toBase58()
|
|
132
128
|
}
|
|
133
129
|
|
|
134
|
-
export function deserializeMetaplexMetadata(rawData
|
|
130
|
+
export function deserializeMetaplexMetadata(rawData) {
|
|
135
131
|
const metadata = deserializeUnchecked(METADATA_SCHEMA, Metadata, rawData)
|
|
136
132
|
|
|
137
133
|
// eslint-disable-next-line no-control-regex
|
package/src/helpers/spl-token.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'assert'
|
|
2
2
|
import BN from 'bn.js'
|
|
3
3
|
import * as BufferLayout from '@exodus/buffer-layout'
|
|
4
|
-
import {
|
|
4
|
+
import { TransactionInstruction } from '../vendor'
|
|
5
5
|
import * as Layout from '../vendor/utils/layout'
|
|
6
6
|
|
|
7
7
|
// Extracted from https://github.com/ExodusMovement/solana-spl-token/blob/master/src/index.js#L263
|
|
@@ -13,7 +13,7 @@ export class U64 extends BN {
|
|
|
13
13
|
/**
|
|
14
14
|
* Convert to Buffer representation
|
|
15
15
|
*/
|
|
16
|
-
toBuffer()
|
|
16
|
+
toBuffer() {
|
|
17
17
|
const a = super.toArray().reverse()
|
|
18
18
|
const b = Buffer.from(a)
|
|
19
19
|
if (b.length === 8) {
|
|
@@ -29,7 +29,7 @@ export class U64 extends BN {
|
|
|
29
29
|
/**
|
|
30
30
|
* Construct a u64 from Buffer representation
|
|
31
31
|
*/
|
|
32
|
-
static fromBuffer(buffer
|
|
32
|
+
static fromBuffer(buffer) {
|
|
33
33
|
assert(buffer.length === 8, `Invalid buffer length: ${buffer.length}`)
|
|
34
34
|
return new U64(
|
|
35
35
|
[...buffer]
|
|
@@ -41,8 +41,6 @@ export class U64 extends BN {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const u64 = U64 // alias
|
|
45
|
-
|
|
46
44
|
/**
|
|
47
45
|
* Layout for a public key
|
|
48
46
|
*/
|
|
@@ -71,14 +69,7 @@ export class Token {
|
|
|
71
69
|
* @param multiSigners Signing accounts if `authority` is a multiSig
|
|
72
70
|
* @param amount Number of tokens to transfer
|
|
73
71
|
*/
|
|
74
|
-
static createTransferInstruction(
|
|
75
|
-
programId: PublicKey,
|
|
76
|
-
source: PublicKey,
|
|
77
|
-
destination: PublicKey,
|
|
78
|
-
owner: PublicKey,
|
|
79
|
-
multiSigners: Array<Account>,
|
|
80
|
-
amount: number | u64
|
|
81
|
-
): TransactionInstruction {
|
|
72
|
+
static createTransferInstruction(programId, source, destination, owner, multiSigners, amount) {
|
|
82
73
|
const dataLayout = BufferLayout.struct([
|
|
83
74
|
BufferLayout.u8('instruction'),
|
|
84
75
|
Layout.uint64('amount'),
|
|
@@ -120,7 +111,7 @@ export class Token {
|
|
|
120
111
|
})
|
|
121
112
|
}
|
|
122
113
|
|
|
123
|
-
static decode(data
|
|
114
|
+
static decode(data) {
|
|
124
115
|
return BufferLayout.struct([
|
|
125
116
|
publicKey('mint'),
|
|
126
117
|
publicKey('owner'),
|
|
@@ -5,9 +5,9 @@ import { findAssociatedTokenAddress } from '../encode'
|
|
|
5
5
|
|
|
6
6
|
// https://github.com/paul-schaaf/spl-token-ui/blob/main/src/solana/token/associatedToken.ts#L59
|
|
7
7
|
export const createAssociatedTokenAccount = (
|
|
8
|
-
senderAddress
|
|
9
|
-
tokenMintAddress
|
|
10
|
-
ownerAddress
|
|
8
|
+
senderAddress,
|
|
9
|
+
tokenMintAddress,
|
|
10
|
+
ownerAddress // destination SOL address
|
|
11
11
|
) => {
|
|
12
12
|
const associatedTokenAccountPublicKey = new PublicKey(
|
|
13
13
|
findAssociatedTokenAddress(ownerAddress, tokenMintAddress)
|
|
@@ -28,10 +28,10 @@ export const createAssociatedTokenAccount = (
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function createIx(
|
|
31
|
-
funderPubkey
|
|
32
|
-
associatedTokenAccountPublicKey
|
|
33
|
-
ownerPublicKey
|
|
34
|
-
tokenMintPublicKey
|
|
31
|
+
funderPubkey,
|
|
32
|
+
associatedTokenAccountPublicKey,
|
|
33
|
+
ownerPublicKey,
|
|
34
|
+
tokenMintPublicKey
|
|
35
35
|
) {
|
|
36
36
|
return new TransactionInstruction({
|
|
37
37
|
programId: SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
|
|
@@ -10,7 +10,7 @@ const isVersionedTransactionTypeSupported = (transaction) => {
|
|
|
10
10
|
return SUPPORTED_TRANSACTION_VERSIONS.has(transaction.version)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const getTransactionStrategy = (transaction)
|
|
13
|
+
const getTransactionStrategy = (transaction) => {
|
|
14
14
|
if (isVersionedTransactionType(transaction)) {
|
|
15
15
|
if (isVersionedTransactionTypeSupported(transaction)) {
|
|
16
16
|
return VersionedTransaction
|
package/src/index.js
CHANGED
package/src/keypair.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import nacl from 'tweetnacl'
|
|
3
2
|
import { PublicKey } from './vendor'
|
|
4
3
|
|
|
5
|
-
export function getKeyPairFromPrivateKey(privateKey
|
|
4
|
+
export function getKeyPairFromPrivateKey(privateKey) {
|
|
6
5
|
const { publicKey, secretKey } = nacl.sign.keyPair.fromSeed(
|
|
7
6
|
Buffer.from(privateKey, 'hex').slice(0, 32)
|
|
8
7
|
)
|
|
@@ -22,21 +21,17 @@ export function generateKeyPair() {
|
|
|
22
21
|
}
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
export function getPublicKey(privateKey
|
|
24
|
+
export function getPublicKey(privateKey) {
|
|
26
25
|
return getKeyPairFromPrivateKey(privateKey).publicKey
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
export function sign(data
|
|
28
|
+
export function sign(data, privateKey) {
|
|
30
29
|
return Buffer.from(
|
|
31
30
|
nacl.sign.detached(data, getKeyPairFromPrivateKey(Buffer.from(privateKey, 'hex')).secretKey),
|
|
32
31
|
'hex'
|
|
33
32
|
)
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
export function verifySignature(
|
|
37
|
-
data: Buffer,
|
|
38
|
-
signature: Buffer,
|
|
39
|
-
publicKey: string | Buffer
|
|
40
|
-
): boolean {
|
|
35
|
+
export function verifySignature(data, signature, publicKey) {
|
|
41
36
|
return nacl.sign.detached.verify(data, signature, Buffer.from(publicKey, 'hex'))
|
|
42
37
|
}
|
package/src/transaction.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import assert from 'assert'
|
|
3
2
|
import BN from 'bn.js'
|
|
4
3
|
import bs58 from 'bs58'
|
|
@@ -354,7 +353,7 @@ class Tx {
|
|
|
354
353
|
return transaction
|
|
355
354
|
}
|
|
356
355
|
|
|
357
|
-
static sign(tx, privateKey
|
|
356
|
+
static sign(tx, privateKey, extraSigners = []) {
|
|
358
357
|
if (!privateKey) throw new Error('Please provide a secretKey')
|
|
359
358
|
const { secretKey } = getKeyPairFromPrivateKey(privateKey)
|
|
360
359
|
const signers = [new Account(secretKey), ...extraSigners]
|
|
@@ -379,7 +378,7 @@ class Tx {
|
|
|
379
378
|
return transaction.serialize().toString('base64')
|
|
380
379
|
}
|
|
381
380
|
|
|
382
|
-
static decodeStakingTx(serialized
|
|
381
|
+
static decodeStakingTx(serialized) {
|
|
383
382
|
// as base64
|
|
384
383
|
const wireTransaction = Buffer.from(serialized, 'base64')
|
|
385
384
|
const tx = Transaction.from(wireTransaction) // Transaction instance
|
|
@@ -3,7 +3,7 @@ import { PACKET_DATA_SIZE } from '../vendor'
|
|
|
3
3
|
|
|
4
4
|
// Copied from:
|
|
5
5
|
// https://github.com/solana-labs/solana-web3.js/blob/42612c936d8d4ddbcb09dbb73db9e1aeaf6d8764/src/util/shortvec-encoding.ts#L15-L28.
|
|
6
|
-
function encodeLength(bytes
|
|
6
|
+
function encodeLength(bytes, length) {
|
|
7
7
|
let remainingLength = length
|
|
8
8
|
|
|
9
9
|
for (;;) {
|
|
@@ -26,8 +26,8 @@ const MAX_SIGNATURES = 255
|
|
|
26
26
|
|
|
27
27
|
export const SIGNATURE_LENGTH = nacl.sign.signatureLength
|
|
28
28
|
|
|
29
|
-
export function buildRawTransaction(signData
|
|
30
|
-
const signatureCount
|
|
29
|
+
export function buildRawTransaction(signData, signatures) {
|
|
30
|
+
const signatureCount = []
|
|
31
31
|
encodeLength(signatureCount, signatures.length)
|
|
32
32
|
|
|
33
33
|
const signaturesLength = signatureCount.length + signatures.length * SIGNATURE_LENGTH
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { createUnsignedTx } from './create-unsigned-tx'
|
|
2
2
|
import { signUnsignedTx } from './sign-unsigned-tx'
|
|
3
|
-
import type { ParsedTransaction, SignedTransaction } from '@exodus/models/lib/types'
|
|
4
3
|
|
|
5
|
-
export function createAndSignTx(input
|
|
4
|
+
export function createAndSignTx(input, privateKey) {
|
|
6
5
|
const unsignedTx = createUnsignedTx(input)
|
|
7
6
|
return signUnsignedTx(unsignedTx, privateKey)
|
|
8
7
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { UnsignedTransaction, ParsedTransaction } from '@exodus/models/lib/types'
|
|
2
|
-
|
|
3
1
|
export function createUnsignedTx({
|
|
4
2
|
asset,
|
|
5
3
|
from,
|
|
@@ -34,7 +32,7 @@ export function createUnsignedTx({
|
|
|
34
32
|
// Wallet Connect
|
|
35
33
|
instructions,
|
|
36
34
|
feePayer,
|
|
37
|
-
}
|
|
35
|
+
}) {
|
|
38
36
|
return {
|
|
39
37
|
txData: {
|
|
40
38
|
from,
|
|
@@ -2,24 +2,9 @@ import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@exodus/solana-sp
|
|
|
2
2
|
import { MARKETS, TokenInstructions } from '@project-serum/serum'
|
|
3
3
|
import * as BufferLayout from '@exodus/buffer-layout'
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
Message,
|
|
7
|
-
SystemInstruction,
|
|
8
|
-
SystemProgram,
|
|
9
|
-
TransactionInstruction,
|
|
10
|
-
PublicKey,
|
|
11
|
-
} from './../vendor'
|
|
5
|
+
import { SystemInstruction, SystemProgram } from './../vendor'
|
|
12
6
|
import bs58 from 'bs58'
|
|
13
7
|
|
|
14
|
-
type DecodedInstruction = {
|
|
15
|
-
type: string,
|
|
16
|
-
title: string,
|
|
17
|
-
data: {
|
|
18
|
-
programId: PublicKey,
|
|
19
|
-
rawData?: Buffer,
|
|
20
|
-
},
|
|
21
|
-
}
|
|
22
|
-
|
|
23
8
|
const INSTRUCTION_LAYOUT = BufferLayout.union(BufferLayout.u8('instruction'))
|
|
24
9
|
INSTRUCTION_LAYOUT.addVariant(
|
|
25
10
|
12,
|
|
@@ -61,12 +46,12 @@ class InstructionKeys {
|
|
|
61
46
|
this.keys = keys
|
|
62
47
|
}
|
|
63
48
|
|
|
64
|
-
getAddress(index
|
|
49
|
+
getAddress(index) {
|
|
65
50
|
return this.keys[index] ? this.keys[index].pubkey : undefined
|
|
66
51
|
}
|
|
67
52
|
}
|
|
68
53
|
|
|
69
|
-
export function getTransactionInstructionsFromMessage(message
|
|
54
|
+
export function getTransactionInstructionsFromMessage(message) {
|
|
70
55
|
const { accountKeys, instructions } = message
|
|
71
56
|
return instructions.map((instruction) => {
|
|
72
57
|
const { accounts, data, programIdIndex } = instruction
|
|
@@ -82,7 +67,7 @@ export function getTransactionInstructionsFromMessage(message: Message): Transac
|
|
|
82
67
|
})
|
|
83
68
|
}
|
|
84
69
|
|
|
85
|
-
function decodeSystemInstruction(instruction
|
|
70
|
+
function decodeSystemInstruction(instruction) {
|
|
86
71
|
const instructionType = SystemInstruction.decodeInstructionType(instruction)
|
|
87
72
|
|
|
88
73
|
let data
|
|
@@ -102,7 +87,7 @@ function decodeSystemInstruction(instruction: TransactionInstruction): DecodedIn
|
|
|
102
87
|
}
|
|
103
88
|
}
|
|
104
89
|
|
|
105
|
-
function decodeTokenInstructionData(data
|
|
90
|
+
function decodeTokenInstructionData(data) {
|
|
106
91
|
if (data.length === 1) {
|
|
107
92
|
switch (data[0]) {
|
|
108
93
|
case 1:
|
|
@@ -128,9 +113,7 @@ function decodeTokenInstructionData(data: Buffer) {
|
|
|
128
113
|
return TokenInstructions.decodeTokenInstructionData(data)
|
|
129
114
|
}
|
|
130
115
|
|
|
131
|
-
export function decodeTokenProgramInstruction(
|
|
132
|
-
instruction: TransactionInstruction
|
|
133
|
-
): DecodedInstruction {
|
|
116
|
+
export function decodeTokenProgramInstruction(instruction) {
|
|
134
117
|
const decodedInstructionData = decodeTokenInstructionData(instruction.data)
|
|
135
118
|
|
|
136
119
|
if (!decodedInstructionData || Object.keys(decodedInstructionData).length > 1) {
|
|
@@ -169,9 +152,7 @@ export function decodeTokenProgramInstruction(
|
|
|
169
152
|
}
|
|
170
153
|
}
|
|
171
154
|
|
|
172
|
-
function decodeAssociatedTokenProgramInstruction(
|
|
173
|
-
instruction: TransactionInstruction
|
|
174
|
-
): DecodedInstruction {
|
|
155
|
+
function decodeAssociatedTokenProgramInstruction(instruction) {
|
|
175
156
|
const { programId } = instruction
|
|
176
157
|
const type = 'createAssociatedTokenAccount'
|
|
177
158
|
return {
|
|
@@ -181,11 +162,11 @@ function decodeAssociatedTokenProgramInstruction(
|
|
|
181
162
|
}
|
|
182
163
|
}
|
|
183
164
|
|
|
184
|
-
function decodeMarketProgramInstruction(instruction
|
|
165
|
+
function decodeMarketProgramInstruction(instruction) {
|
|
185
166
|
throw new Error('Not yet implemented')
|
|
186
167
|
}
|
|
187
168
|
|
|
188
|
-
function decodeTokenInstruction(instruction
|
|
169
|
+
function decodeTokenInstruction(instruction) {
|
|
189
170
|
const { programId } = instruction
|
|
190
171
|
|
|
191
172
|
try {
|
|
@@ -215,24 +196,19 @@ function decodeTokenInstruction(instruction: TransactionInstruction): DecodedIns
|
|
|
215
196
|
}
|
|
216
197
|
}
|
|
217
198
|
|
|
218
|
-
export function decodeTransactionInstructions(
|
|
219
|
-
transactionMessages
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
return [...prevInstructions, ...instructions]
|
|
233
|
-
},
|
|
234
|
-
[]
|
|
235
|
-
)
|
|
199
|
+
export function decodeTransactionInstructions(transactionMessages) {
|
|
200
|
+
const transactionInstructions = transactionMessages.reduce((prevInstructions, message) => {
|
|
201
|
+
let instructions
|
|
202
|
+
const isTransactionMessage =
|
|
203
|
+
message.instructions.length > 0 && message.instructions[0].programId !== undefined
|
|
204
|
+
if (isTransactionMessage) {
|
|
205
|
+
instructions = message.instructions
|
|
206
|
+
} else {
|
|
207
|
+
instructions = getTransactionInstructionsFromMessage(message)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return [...prevInstructions, ...instructions]
|
|
211
|
+
}, [])
|
|
236
212
|
return transactionInstructions.map((instruction) => {
|
|
237
213
|
if (instruction.programId.equals(SystemProgram.programId)) {
|
|
238
214
|
return decodeSystemInstruction(instruction)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { asset } from '@exodus/solana-meta'
|
|
2
|
-
import type { UnsignedTransaction, ParsedTransaction } from '@exodus/models/lib/types'
|
|
3
2
|
|
|
4
|
-
export function parseUnsignedTx(unsignedTx
|
|
3
|
+
export function parseUnsignedTx(unsignedTx) {
|
|
5
4
|
const {
|
|
6
5
|
from,
|
|
7
6
|
to,
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { asset } from '@exodus/solana-meta'
|
|
2
|
-
import type { UnsignedTransaction, SignedTransaction } from '@exodus/models/lib/types'
|
|
3
2
|
|
|
4
3
|
import { Transaction, getTransactionStrategy } from '../'
|
|
5
4
|
import { createMetaplexTransferTransaction } from '../helpers/metaplex-transfer'
|
|
6
5
|
|
|
7
|
-
export function signUnsignedTx(
|
|
8
|
-
unsignedTx: UnsignedTransaction,
|
|
9
|
-
privateKey: Buffer
|
|
10
|
-
): SignedTransaction {
|
|
6
|
+
export function signUnsignedTx(unsignedTx, privateKey) {
|
|
11
7
|
const { amount: unitAmount, from, method, transaction } = unsignedTx.txData
|
|
12
8
|
|
|
13
9
|
if (transaction) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Token, U64 } from '../helpers/spl-token'
|
|
2
2
|
import { PublicKey } from '../vendor/'
|
|
3
3
|
|
|
4
|
-
export function computeBalance(futureAccountBalance
|
|
4
|
+
export function computeBalance(futureAccountBalance, currentAccountBalance) {
|
|
5
5
|
return new U64(futureAccountBalance).sub(new U64(currentAccountBalance))
|
|
6
6
|
}
|
|
7
7
|
|
package/src/vendor/account.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
import type { KeyPair } from 'tweetnacl'
|
|
3
1
|
import { PublicKey } from './publickey'
|
|
4
2
|
import { getKeyPairFromPrivateKey } from '../keypair'
|
|
5
3
|
|
|
@@ -7,14 +5,14 @@ import { getKeyPairFromPrivateKey } from '../keypair'
|
|
|
7
5
|
* An account key pair (public and secret keys).
|
|
8
6
|
*/
|
|
9
7
|
export class Account {
|
|
10
|
-
_keypair
|
|
8
|
+
_keypair
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* Create a new Account object
|
|
14
12
|
*
|
|
15
13
|
* @param secretKey Secret key for the account
|
|
16
14
|
*/
|
|
17
|
-
constructor(secretKey
|
|
15
|
+
constructor(secretKey) {
|
|
18
16
|
if (secretKey) {
|
|
19
17
|
this._keypair = getKeyPairFromPrivateKey(Buffer.from(secretKey, 'hex'))
|
|
20
18
|
} else {
|
|
@@ -25,14 +23,14 @@ export class Account {
|
|
|
25
23
|
/**
|
|
26
24
|
* The public key for this account
|
|
27
25
|
*/
|
|
28
|
-
get publicKey()
|
|
26
|
+
get publicKey() {
|
|
29
27
|
return new PublicKey(this._keypair.publicKey)
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
/**
|
|
33
31
|
* The **unencrypted** secret key for this account
|
|
34
32
|
*/
|
|
35
|
-
get secretKey()
|
|
33
|
+
get secretKey() {
|
|
36
34
|
return this._keypair.secretKey
|
|
37
35
|
}
|
|
38
36
|
}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import * as BufferLayout from '@exodus/buffer-layout'
|
|
4
|
-
|
|
5
1
|
import * as Layout from './utils/layout'
|
|
6
2
|
|
|
7
3
|
/**
|
|
@@ -9,15 +5,11 @@ import * as Layout from './utils/layout'
|
|
|
9
5
|
* @property (index} The Instruction index (from solana upstream program)
|
|
10
6
|
* @property (BufferLayout} The BufferLayout to use to build data
|
|
11
7
|
*/
|
|
12
|
-
export type InstructionType = {|
|
|
13
|
-
index: number,
|
|
14
|
-
layout: typeof BufferLayout,
|
|
15
|
-
|}
|
|
16
8
|
|
|
17
9
|
/**
|
|
18
10
|
* Populate a buffer of instruction data using an InstructionType
|
|
19
11
|
*/
|
|
20
|
-
export function encodeData(type
|
|
12
|
+
export function encodeData(type, fields) {
|
|
21
13
|
const allocLength = type.layout.span >= 0 ? type.layout.span : Layout.getAlloc(type, fields)
|
|
22
14
|
const data = Buffer.alloc(allocLength)
|
|
23
15
|
const layoutFields = Object.assign({ instruction: type.index }, fields)
|
|
@@ -28,7 +20,7 @@ export function encodeData(type: InstructionType, fields: Object): Buffer {
|
|
|
28
20
|
/**
|
|
29
21
|
* Decode instruction data buffer using an InstructionType
|
|
30
22
|
*/
|
|
31
|
-
export function decodeData(type
|
|
23
|
+
export function decodeData(type, buffer) {
|
|
32
24
|
let data
|
|
33
25
|
try {
|
|
34
26
|
data = type.layout.decode(buffer)
|
package/src/vendor/message.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
1
|
import bs58 from 'bs58'
|
|
4
2
|
import * as BufferLayout from '@exodus/buffer-layout'
|
|
5
3
|
|
|
6
4
|
import { PublicKey } from './publickey'
|
|
7
|
-
|
|
5
|
+
|
|
8
6
|
import * as Layout from './utils/layout'
|
|
9
7
|
import { PACKET_DATA_SIZE } from './transaction'
|
|
10
8
|
import * as shortvec from './utils/shortvec-encoding'
|
|
@@ -18,11 +16,6 @@ import * as shortvec from './utils/shortvec-encoding'
|
|
|
18
16
|
* @property {number} numReadonlySignedAccounts: The last `numReadonlySignedAccounts` of the signed keys are read-only accounts
|
|
19
17
|
* @property {number} numReadonlyUnsignedAccounts The last `numReadonlySignedAccounts` of the unsigned keys are read-only accounts
|
|
20
18
|
*/
|
|
21
|
-
export type MessageHeader = {
|
|
22
|
-
numRequiredSignatures: number,
|
|
23
|
-
numReadonlySignedAccounts: number,
|
|
24
|
-
numReadonlyUnsignedAccounts: number,
|
|
25
|
-
}
|
|
26
19
|
|
|
27
20
|
/**
|
|
28
21
|
* An instruction to execute by a program
|
|
@@ -32,11 +25,6 @@ export type MessageHeader = {
|
|
|
32
25
|
* @property {number[]} accounts Ordered indices into the transaction keys array indicating which accounts to pass to the program
|
|
33
26
|
* @property {string} data The program input data encoded as base 58
|
|
34
27
|
*/
|
|
35
|
-
export type CompiledInstruction = {
|
|
36
|
-
programIdIndex: number,
|
|
37
|
-
accounts: number[],
|
|
38
|
-
data: string,
|
|
39
|
-
}
|
|
40
28
|
|
|
41
29
|
/**
|
|
42
30
|
* Message constructor arguments
|
|
@@ -47,12 +35,6 @@ export type CompiledInstruction = {
|
|
|
47
35
|
* @property {Blockhash} recentBlockhash The hash of a recent ledger block
|
|
48
36
|
* @property {CompiledInstruction[]} instructions Instructions that will be executed in sequence and committed in one atomic transaction if all succeed.
|
|
49
37
|
*/
|
|
50
|
-
type MessageArgs = {
|
|
51
|
-
header: MessageHeader,
|
|
52
|
-
accountKeys: string[],
|
|
53
|
-
recentBlockhash: Blockhash,
|
|
54
|
-
instructions: CompiledInstruction[],
|
|
55
|
-
}
|
|
56
38
|
|
|
57
39
|
const PUBKEY_LENGTH = 32
|
|
58
40
|
|
|
@@ -60,23 +42,23 @@ const PUBKEY_LENGTH = 32
|
|
|
60
42
|
* List of instructions to be processed atomically
|
|
61
43
|
*/
|
|
62
44
|
export class Message {
|
|
63
|
-
header
|
|
64
|
-
accountKeys
|
|
65
|
-
recentBlockhash
|
|
66
|
-
instructions
|
|
45
|
+
header
|
|
46
|
+
accountKeys
|
|
47
|
+
recentBlockhash
|
|
48
|
+
instructions
|
|
67
49
|
|
|
68
|
-
constructor(args
|
|
50
|
+
constructor(args) {
|
|
69
51
|
this.header = args.header
|
|
70
52
|
this.accountKeys = args.accountKeys.map((account) => new PublicKey(account))
|
|
71
53
|
this.recentBlockhash = args.recentBlockhash
|
|
72
54
|
this.instructions = args.instructions
|
|
73
55
|
}
|
|
74
56
|
|
|
75
|
-
isAccountSigner(index
|
|
57
|
+
isAccountSigner(index) {
|
|
76
58
|
return index < this.header.numRequiredSignatures
|
|
77
59
|
}
|
|
78
60
|
|
|
79
|
-
isAccountWritable(index
|
|
61
|
+
isAccountWritable(index) {
|
|
80
62
|
return (
|
|
81
63
|
index < this.header.numRequiredSignatures - this.header.numReadonlySignedAccounts ||
|
|
82
64
|
(index >= this.header.numRequiredSignatures &&
|
|
@@ -84,7 +66,7 @@ export class Message {
|
|
|
84
66
|
)
|
|
85
67
|
}
|
|
86
68
|
|
|
87
|
-
findSignerIndex(signer
|
|
69
|
+
findSignerIndex(signer) {
|
|
88
70
|
const index = this.accountKeys.findIndex((accountKey) => {
|
|
89
71
|
return accountKey.equals(signer)
|
|
90
72
|
})
|
|
@@ -94,7 +76,7 @@ export class Message {
|
|
|
94
76
|
return index
|
|
95
77
|
}
|
|
96
78
|
|
|
97
|
-
serialize()
|
|
79
|
+
serialize() {
|
|
98
80
|
const numKeys = this.accountKeys.length
|
|
99
81
|
|
|
100
82
|
let keyCount = []
|
|
@@ -170,7 +152,7 @@ export class Message {
|
|
|
170
152
|
/**
|
|
171
153
|
* Decode a compiled message into a Message object.
|
|
172
154
|
*/
|
|
173
|
-
static from(buffer
|
|
155
|
+
static from(buffer) {
|
|
174
156
|
// Slice up wire data
|
|
175
157
|
let byteArray = [...buffer]
|
|
176
158
|
|