@exodus/solana-lib 1.6.10 → 1.7.0
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 +2 -2
- package/src/index.js +1 -3
- package/src/key-identifier.js +31 -10
- package/src/tx/common.js +47 -0
- package/src/tx/index.js +1 -0
- package/src/tx/prepare-for-signing.js +185 -0
- package/src/tx/sign-hardware.js +44 -0
- package/src/tx/sign-unsigned-tx.js +17 -173
- package/src/vendor/publickey.js +8 -0
- package/src/helpers/transaction-strategy.js +0 -25
- package/src/versioned-transaction.js +0 -45
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/solana-lib",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Exodus internal Solana low-level library",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"lodash": "^4.17.11",
|
|
28
28
|
"tweetnacl": "^1.0.3"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "d0aa3d128fe488e0d4849923e5b134b80b6fef97"
|
|
31
31
|
}
|
package/src/index.js
CHANGED
|
@@ -12,6 +12,4 @@ export {
|
|
|
12
12
|
} from './vendor'
|
|
13
13
|
export { default as Transaction } from './transaction'
|
|
14
14
|
export { U64 } from './helpers/spl-token'
|
|
15
|
-
export {
|
|
16
|
-
export { default as getTransactionStrategy } from './helpers/transaction-strategy'
|
|
17
|
-
export { default as VersionedTransaction } from './versioned-transaction'
|
|
15
|
+
export { createGetKeyIdentifier, getSupportedPurposes } from './key-identifier'
|
package/src/key-identifier.js
CHANGED
|
@@ -1,36 +1,57 @@
|
|
|
1
1
|
import assert from 'minimalistic-assert'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
createGetKeyIdentifier as _createGetKeyIdentifier,
|
|
4
|
+
unhardenDerivationIndex,
|
|
5
|
+
} from '@exodus/key-utils'
|
|
3
6
|
|
|
4
|
-
export
|
|
7
|
+
export const getSupportedPurposes = () => [44]
|
|
8
|
+
|
|
9
|
+
export const createGetKeyIdentifier = ({ bip44 } = {}) => (partialParams = {}) => {
|
|
5
10
|
assert(typeof bip44 === 'number', 'bip44 must be a number')
|
|
6
11
|
|
|
7
|
-
const
|
|
12
|
+
const params = {
|
|
13
|
+
chainIndex: 0,
|
|
14
|
+
addressIndex: 0,
|
|
15
|
+
...partialParams,
|
|
16
|
+
}
|
|
8
17
|
const unhardenedBip44 = unhardenDerivationIndex(bip44)
|
|
18
|
+
const { compatibilityMode, purpose, accountIndex, addressIndex } = params
|
|
19
|
+
|
|
20
|
+
const allowedPurposes = getSupportedPurposes()
|
|
21
|
+
assert(
|
|
22
|
+
allowedPurposes.includes(purpose),
|
|
23
|
+
`purpose was ${purpose}, which is not allowed. Can be one of the following: ${allowedPurposes.join(
|
|
24
|
+
', '
|
|
25
|
+
)}`
|
|
26
|
+
)
|
|
9
27
|
|
|
10
28
|
switch (compatibilityMode) {
|
|
11
29
|
case 'phantom':
|
|
12
30
|
// Phantom doesn't use chainIndex (normal vs change address)
|
|
13
31
|
return {
|
|
14
|
-
assetName,
|
|
15
32
|
derivationAlgorithm: 'SLIP10',
|
|
16
33
|
derivationPath: `m/${purpose}'/${unhardenedBip44}'/${accountIndex}'/${addressIndex}'`,
|
|
17
|
-
keyType,
|
|
34
|
+
keyType: 'nacl',
|
|
35
|
+
}
|
|
36
|
+
case 'ledger':
|
|
37
|
+
return {
|
|
38
|
+
derivationAlgorithm: 'SLIP10',
|
|
39
|
+
derivationPath: `m/${purpose}'/${unhardenedBip44}'/${accountIndex}'`,
|
|
40
|
+
keyType: 'nacl',
|
|
18
41
|
}
|
|
19
42
|
case 'trust':
|
|
20
43
|
return {
|
|
21
|
-
assetName,
|
|
22
44
|
derivationAlgorithm: 'SLIP10',
|
|
23
45
|
derivationPath: `m/${purpose}'/${unhardenedBip44}'/${accountIndex}'`,
|
|
24
|
-
keyType,
|
|
46
|
+
keyType: 'nacl',
|
|
25
47
|
}
|
|
26
48
|
case 'mathwallet':
|
|
27
49
|
return {
|
|
28
|
-
assetName,
|
|
29
50
|
derivationAlgorithm: 'BIP32',
|
|
30
51
|
derivationPath: `m/${purpose}'/${unhardenedBip44}'/${accountIndex}'/${addressIndex}`,
|
|
31
|
-
keyType,
|
|
52
|
+
keyType: 'nacl',
|
|
32
53
|
}
|
|
33
54
|
default:
|
|
34
|
-
return
|
|
55
|
+
return _createGetKeyIdentifier({ bip44, keyType: 'nacl' })(params)
|
|
35
56
|
}
|
|
36
57
|
}
|
package/src/tx/common.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import base58 from 'bs58'
|
|
2
|
+
|
|
3
|
+
export function isVersionedTransaction(tx) {
|
|
4
|
+
return Number.isInteger(tx.version)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function isLegacyTransaction(tx) {
|
|
8
|
+
return !isVersionedTransaction(tx)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function getTxId(tx) {
|
|
12
|
+
const signature = getFirstSignature(tx)
|
|
13
|
+
if (signature === null) {
|
|
14
|
+
throw new Error('Cannot get transaction ID of unsigned transaction')
|
|
15
|
+
}
|
|
16
|
+
return base58.encode(signature)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getFirstSignature(tx) {
|
|
20
|
+
if (isVersionedTransaction(tx)) {
|
|
21
|
+
// Versioned
|
|
22
|
+
if (tx.signatures.length > 0) {
|
|
23
|
+
return tx.signatures[0]
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
// Legacy
|
|
27
|
+
if (tx.signatures.length > 0) {
|
|
28
|
+
return tx.signatures[0].signature
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const extractTransaction = ({ tx }) => {
|
|
36
|
+
const serializedTransaction = tx.serialize({
|
|
37
|
+
// Override the default, we don't require all signatures
|
|
38
|
+
// when interacting with dApps. Only affects legacy transactions,
|
|
39
|
+
// because versioned transactions won't be doing this check anymore.
|
|
40
|
+
requireAllSignatures: false,
|
|
41
|
+
verifySignatures: true,
|
|
42
|
+
})
|
|
43
|
+
const rawTx = Buffer.from(serializedTransaction).toString('base64')
|
|
44
|
+
const txId = getTxId(tx)
|
|
45
|
+
|
|
46
|
+
return { txId, rawTx }
|
|
47
|
+
}
|
package/src/tx/index.js
CHANGED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { asset } from '@exodus/solana-meta'
|
|
2
|
+
|
|
3
|
+
import { Transaction, PublicKey } from '../'
|
|
4
|
+
import { createMetaplexTransferTransaction } from '../helpers/metaplex-transfer'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Prepares the transaction to be signed (exodus & ledger).
|
|
8
|
+
* @param {UnsignedTx} unsignedTx
|
|
9
|
+
* @returns a Solana Web3.js Transaction object
|
|
10
|
+
*/
|
|
11
|
+
export function prepareForSigning(unsignedTx) {
|
|
12
|
+
const { amount: unitAmount, from, method, transaction } = unsignedTx.txData
|
|
13
|
+
|
|
14
|
+
if (transaction) {
|
|
15
|
+
// unsignedTx contained a transaction in web3.js format
|
|
16
|
+
return transaction
|
|
17
|
+
} else {
|
|
18
|
+
// Create
|
|
19
|
+
const address = from
|
|
20
|
+
const amount = unitAmount ? asset.currency.baseUnit(unitAmount).toNumber() : unitAmount
|
|
21
|
+
|
|
22
|
+
const txData = { ...unsignedTx.txData, address, amount }
|
|
23
|
+
|
|
24
|
+
const { transaction } = createTx({ txData, method })
|
|
25
|
+
|
|
26
|
+
if (!transaction.feePayer) {
|
|
27
|
+
transaction.feePayer = new PublicKey(from)
|
|
28
|
+
}
|
|
29
|
+
return transaction
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const createTx = ({ txData, method }) => {
|
|
34
|
+
let tx
|
|
35
|
+
switch (method) {
|
|
36
|
+
case 'delegate':
|
|
37
|
+
tx = createDelegateTransaction(txData)
|
|
38
|
+
break
|
|
39
|
+
case 'undelegate':
|
|
40
|
+
tx = createUndelegateTransaction(txData)
|
|
41
|
+
break
|
|
42
|
+
case 'withdraw':
|
|
43
|
+
tx = createWithdrawTransaction(txData)
|
|
44
|
+
break
|
|
45
|
+
case 'closeAccount':
|
|
46
|
+
tx = createCloseAccountTransaction(txData)
|
|
47
|
+
break
|
|
48
|
+
case 'initializeEscrow': {
|
|
49
|
+
tx = createMagicEdenInitializeEscrowTransaction(txData)
|
|
50
|
+
break
|
|
51
|
+
}
|
|
52
|
+
case 'cancelEscrow':
|
|
53
|
+
tx = createMagicEdenCancelEscrowTransaction(txData)
|
|
54
|
+
break
|
|
55
|
+
case 'exchange':
|
|
56
|
+
tx = createMagicEdenExchangeTransaction(txData)
|
|
57
|
+
break
|
|
58
|
+
case 'metaplexTransfer':
|
|
59
|
+
tx = createMetaplexTransferTransaction(txData)
|
|
60
|
+
break
|
|
61
|
+
default:
|
|
62
|
+
// SOL and Token tx
|
|
63
|
+
tx = createTokenTransaction(txData)
|
|
64
|
+
break
|
|
65
|
+
}
|
|
66
|
+
return tx
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const createDelegateTransaction = ({ address, amount, pool, recentBlockhash, seed }) =>
|
|
70
|
+
Transaction.createStakeAccountTransaction({
|
|
71
|
+
address,
|
|
72
|
+
amount,
|
|
73
|
+
recentBlockhash,
|
|
74
|
+
seed,
|
|
75
|
+
pool,
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const createUndelegateTransaction = ({ address, recentBlockhash, stakeAddresses }) =>
|
|
79
|
+
Transaction.undelegate({
|
|
80
|
+
address,
|
|
81
|
+
recentBlockhash,
|
|
82
|
+
stakeAddresses,
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const createWithdrawTransaction = ({ address, amount, recentBlockhash, stakeAddresses }) =>
|
|
86
|
+
Transaction.withdraw({
|
|
87
|
+
address,
|
|
88
|
+
amount,
|
|
89
|
+
recentBlockhash,
|
|
90
|
+
stakeAddresses,
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const createMagicEdenInitializeEscrowTransaction = ({
|
|
94
|
+
escrowAddress,
|
|
95
|
+
escrowBump,
|
|
96
|
+
initializerDepositTokenAddress,
|
|
97
|
+
recentBlockhash,
|
|
98
|
+
takerAmount,
|
|
99
|
+
initializerAddress,
|
|
100
|
+
}) =>
|
|
101
|
+
Transaction.magicEdenInitializeEscrow({
|
|
102
|
+
escrowAddress,
|
|
103
|
+
escrowBump,
|
|
104
|
+
initializerAddress,
|
|
105
|
+
initializerDepositTokenAddress,
|
|
106
|
+
recentBlockhash,
|
|
107
|
+
takerAmount,
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const createMagicEdenCancelEscrowTransaction = ({
|
|
111
|
+
escrowAddress,
|
|
112
|
+
initializerAddress,
|
|
113
|
+
initializerDepositTokenAddress,
|
|
114
|
+
pdaAddress,
|
|
115
|
+
recentBlockhash,
|
|
116
|
+
}) =>
|
|
117
|
+
Transaction.magicEdenCancelEscrow({
|
|
118
|
+
escrowAddress,
|
|
119
|
+
initializerAddress,
|
|
120
|
+
initializerDepositTokenAddress,
|
|
121
|
+
pdaAddress,
|
|
122
|
+
recentBlockhash,
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const createMagicEdenExchangeTransaction = ({
|
|
126
|
+
creators,
|
|
127
|
+
escrowAddress,
|
|
128
|
+
expectedMintAddress,
|
|
129
|
+
expectedTakerAmount,
|
|
130
|
+
initializerAddress,
|
|
131
|
+
initializerDepositTokenAddress,
|
|
132
|
+
metadataAddress,
|
|
133
|
+
pdaAddress,
|
|
134
|
+
recentBlockhash,
|
|
135
|
+
takerAddress,
|
|
136
|
+
}) =>
|
|
137
|
+
Transaction.magicEdenExchange({
|
|
138
|
+
creators,
|
|
139
|
+
escrowAddress,
|
|
140
|
+
expectedMintAddress,
|
|
141
|
+
expectedTakerAmount,
|
|
142
|
+
initializerAddress,
|
|
143
|
+
initializerDepositTokenAddress,
|
|
144
|
+
metadataAddress,
|
|
145
|
+
pdaAddress,
|
|
146
|
+
recentBlockhash,
|
|
147
|
+
takerAddress,
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
const createTokenTransaction = ({
|
|
151
|
+
amount,
|
|
152
|
+
destinationAddressType,
|
|
153
|
+
feePayer,
|
|
154
|
+
from,
|
|
155
|
+
fromTokenAddresses,
|
|
156
|
+
instructions,
|
|
157
|
+
isAssociatedTokenAccountActive,
|
|
158
|
+
recentBlockhash,
|
|
159
|
+
to,
|
|
160
|
+
tokenMintAddress,
|
|
161
|
+
memo,
|
|
162
|
+
reference,
|
|
163
|
+
}) =>
|
|
164
|
+
new Transaction({
|
|
165
|
+
amount,
|
|
166
|
+
destinationAddressType,
|
|
167
|
+
feePayer,
|
|
168
|
+
from,
|
|
169
|
+
fromTokenAddresses,
|
|
170
|
+
instructions,
|
|
171
|
+
isAssociatedTokenAccountActive,
|
|
172
|
+
recentBlockhash,
|
|
173
|
+
to,
|
|
174
|
+
tokenMintAddress,
|
|
175
|
+
memo,
|
|
176
|
+
reference,
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
const createCloseAccountTransaction = ({ account, programId, recentBlockhash, walletPublicKey }) =>
|
|
180
|
+
Transaction.createCloseAccount({
|
|
181
|
+
account,
|
|
182
|
+
programId,
|
|
183
|
+
recentBlockhash,
|
|
184
|
+
walletPublicKey,
|
|
185
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import assert from 'minimalistic-assert'
|
|
2
|
+
|
|
3
|
+
import { prepareForSigning } from './prepare-for-signing'
|
|
4
|
+
import { PublicKey } from '../vendor'
|
|
5
|
+
import { isVersionedTransaction, isLegacyTransaction, extractTransaction } from './common'
|
|
6
|
+
|
|
7
|
+
export async function signHardware({ unsignedTx, hardwareDevice, accountIndex }) {
|
|
8
|
+
assert(hardwareDevice, 'expected hardwareDevice to be defined')
|
|
9
|
+
assert(Number.isInteger(accountIndex) && accountIndex >= 0, 'expected accountIndex to be integer')
|
|
10
|
+
|
|
11
|
+
const tx = prepareForSigning(unsignedTx)
|
|
12
|
+
const signatures = await signWithHardwareWallet({ tx, hardwareDevice, accountIndex })
|
|
13
|
+
applySignatures({ tx, signatures })
|
|
14
|
+
|
|
15
|
+
return extractTransaction({ tx })
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const signWithHardwareWallet = async ({ tx, hardwareDevice, accountIndex }) => {
|
|
19
|
+
assert(hardwareDevice, `hardwareDevice required`)
|
|
20
|
+
assert(Number.isInteger(accountIndex), `accountIndex required`)
|
|
21
|
+
|
|
22
|
+
const messageToSign = isVersionedTransaction(tx)
|
|
23
|
+
? tx.message.serialize()
|
|
24
|
+
: tx.compileMessage().serialize()
|
|
25
|
+
|
|
26
|
+
const signatures = await hardwareDevice.signTransaction({
|
|
27
|
+
assetName: 'solana',
|
|
28
|
+
signableTransaction: Buffer.from(messageToSign),
|
|
29
|
+
derivationPaths: [`m/44'/501'/${accountIndex}'`],
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
return signatures
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const applySignatures = ({ tx, signatures }) => {
|
|
36
|
+
if (isLegacyTransaction(tx)) {
|
|
37
|
+
const publicKeys = signatures.map(({ publicKey }) => new PublicKey(publicKey))
|
|
38
|
+
tx.setSigners(...publicKeys)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
signatures.forEach(({ publicKey, signature }) => {
|
|
42
|
+
tx.addSignature(new PublicKey(publicKey), signature)
|
|
43
|
+
})
|
|
44
|
+
}
|
|
@@ -1,185 +1,29 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assert from 'minimalistic-assert'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { prepareForSigning } from './prepare-for-signing'
|
|
4
|
+
import { getKeyPairFromPrivateKey } from '../keypair'
|
|
5
|
+
import { Account } from '../vendor'
|
|
6
|
+
import { extractTransaction, isVersionedTransaction } from './common'
|
|
5
7
|
|
|
6
8
|
export function signUnsignedTx(unsignedTx, privateKey) {
|
|
7
|
-
|
|
9
|
+
assert(privateKey, 'Please provide a secretKey')
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
return _signTx({ tx: transaction, privateKey })
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const address = from
|
|
14
|
-
const amount = unitAmount ? asset.currency.baseUnit(unitAmount).toNumber() : unitAmount
|
|
11
|
+
const tx = prepareForSigning(unsignedTx)
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
_signTx({ tx, privateKey })
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
return _signTx({ tx, privateKey })
|
|
15
|
+
return extractTransaction({ tx })
|
|
20
16
|
}
|
|
21
17
|
|
|
22
18
|
// Signs plain tx.
|
|
23
19
|
const _signTx = ({ tx, privateKey }) => {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const createTx = ({ txData, method }) => {
|
|
34
|
-
let tx
|
|
35
|
-
switch (method) {
|
|
36
|
-
case 'delegate':
|
|
37
|
-
tx = createDelegateTransaction(txData)
|
|
38
|
-
break
|
|
39
|
-
case 'undelegate':
|
|
40
|
-
tx = createUndelegateTransaction(txData)
|
|
41
|
-
break
|
|
42
|
-
case 'withdraw':
|
|
43
|
-
tx = createWithdrawTransaction(txData)
|
|
44
|
-
break
|
|
45
|
-
case 'closeAccount':
|
|
46
|
-
tx = createCloseAccountTransaction(txData)
|
|
47
|
-
break
|
|
48
|
-
case 'initializeEscrow': {
|
|
49
|
-
tx = createMagicEdenInitializeEscrowTransaction(txData)
|
|
50
|
-
break
|
|
51
|
-
}
|
|
52
|
-
case 'cancelEscrow':
|
|
53
|
-
tx = createMagicEdenCancelEscrowTransaction(txData)
|
|
54
|
-
break
|
|
55
|
-
case 'exchange':
|
|
56
|
-
tx = createMagicEdenExchangeTransaction(txData)
|
|
57
|
-
break
|
|
58
|
-
case 'metaplexTransfer':
|
|
59
|
-
tx = createMetaplexTransferTransaction(txData)
|
|
60
|
-
break
|
|
61
|
-
default:
|
|
62
|
-
// SOL and Token tx
|
|
63
|
-
tx = createTokenTransaction(txData)
|
|
64
|
-
break
|
|
20
|
+
const { secretKey } = getKeyPairFromPrivateKey(privateKey)
|
|
21
|
+
const account = new Account(secretKey)
|
|
22
|
+
if (isVersionedTransaction(tx)) {
|
|
23
|
+
// VersionedTransaction
|
|
24
|
+
tx.sign([account])
|
|
25
|
+
} else {
|
|
26
|
+
// Legacy Transactions
|
|
27
|
+
tx.sign(account)
|
|
65
28
|
}
|
|
66
|
-
return tx
|
|
67
29
|
}
|
|
68
|
-
|
|
69
|
-
const createDelegateTransaction = ({ address, amount, pool, recentBlockhash, seed }) =>
|
|
70
|
-
Transaction.createStakeAccountTransaction({
|
|
71
|
-
address,
|
|
72
|
-
amount,
|
|
73
|
-
recentBlockhash,
|
|
74
|
-
seed,
|
|
75
|
-
pool,
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
const createUndelegateTransaction = ({ address, recentBlockhash, stakeAddresses }) =>
|
|
79
|
-
Transaction.undelegate({
|
|
80
|
-
address,
|
|
81
|
-
recentBlockhash,
|
|
82
|
-
stakeAddresses,
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
const createWithdrawTransaction = ({ address, amount, recentBlockhash, stakeAddresses }) =>
|
|
86
|
-
Transaction.withdraw({
|
|
87
|
-
address,
|
|
88
|
-
amount,
|
|
89
|
-
recentBlockhash,
|
|
90
|
-
stakeAddresses,
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
const createMagicEdenInitializeEscrowTransaction = ({
|
|
94
|
-
escrowAddress,
|
|
95
|
-
escrowBump,
|
|
96
|
-
initializerDepositTokenAddress,
|
|
97
|
-
recentBlockhash,
|
|
98
|
-
takerAmount,
|
|
99
|
-
initializerAddress,
|
|
100
|
-
}) =>
|
|
101
|
-
Transaction.magicEdenInitializeEscrow({
|
|
102
|
-
escrowAddress,
|
|
103
|
-
escrowBump,
|
|
104
|
-
initializerAddress,
|
|
105
|
-
initializerDepositTokenAddress,
|
|
106
|
-
recentBlockhash,
|
|
107
|
-
takerAmount,
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
const createMagicEdenCancelEscrowTransaction = ({
|
|
111
|
-
escrowAddress,
|
|
112
|
-
initializerAddress,
|
|
113
|
-
initializerDepositTokenAddress,
|
|
114
|
-
pdaAddress,
|
|
115
|
-
recentBlockhash,
|
|
116
|
-
}) =>
|
|
117
|
-
Transaction.magicEdenCancelEscrow({
|
|
118
|
-
escrowAddress,
|
|
119
|
-
initializerAddress,
|
|
120
|
-
initializerDepositTokenAddress,
|
|
121
|
-
pdaAddress,
|
|
122
|
-
recentBlockhash,
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
const createMagicEdenExchangeTransaction = ({
|
|
126
|
-
creators,
|
|
127
|
-
escrowAddress,
|
|
128
|
-
expectedMintAddress,
|
|
129
|
-
expectedTakerAmount,
|
|
130
|
-
initializerAddress,
|
|
131
|
-
initializerDepositTokenAddress,
|
|
132
|
-
metadataAddress,
|
|
133
|
-
pdaAddress,
|
|
134
|
-
recentBlockhash,
|
|
135
|
-
takerAddress,
|
|
136
|
-
}) =>
|
|
137
|
-
Transaction.magicEdenExchange({
|
|
138
|
-
creators,
|
|
139
|
-
escrowAddress,
|
|
140
|
-
expectedMintAddress,
|
|
141
|
-
expectedTakerAmount,
|
|
142
|
-
initializerAddress,
|
|
143
|
-
initializerDepositTokenAddress,
|
|
144
|
-
metadataAddress,
|
|
145
|
-
pdaAddress,
|
|
146
|
-
recentBlockhash,
|
|
147
|
-
takerAddress,
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
const createTokenTransaction = ({
|
|
151
|
-
amount,
|
|
152
|
-
destinationAddressType,
|
|
153
|
-
feePayer,
|
|
154
|
-
from,
|
|
155
|
-
fromTokenAddresses,
|
|
156
|
-
instructions,
|
|
157
|
-
isAssociatedTokenAccountActive,
|
|
158
|
-
recentBlockhash,
|
|
159
|
-
to,
|
|
160
|
-
tokenMintAddress,
|
|
161
|
-
memo,
|
|
162
|
-
reference,
|
|
163
|
-
}) =>
|
|
164
|
-
new Transaction({
|
|
165
|
-
amount,
|
|
166
|
-
destinationAddressType,
|
|
167
|
-
feePayer,
|
|
168
|
-
from,
|
|
169
|
-
fromTokenAddresses,
|
|
170
|
-
instructions,
|
|
171
|
-
isAssociatedTokenAccountActive,
|
|
172
|
-
recentBlockhash,
|
|
173
|
-
to,
|
|
174
|
-
tokenMintAddress,
|
|
175
|
-
memo,
|
|
176
|
-
reference,
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
const createCloseAccountTransaction = ({ account, programId, recentBlockhash, walletPublicKey }) =>
|
|
180
|
-
Transaction.createCloseAccount({
|
|
181
|
-
account,
|
|
182
|
-
programId,
|
|
183
|
-
recentBlockhash,
|
|
184
|
-
walletPublicKey,
|
|
185
|
-
})
|
package/src/vendor/publickey.js
CHANGED
|
@@ -51,6 +51,14 @@ export class PublicKey {
|
|
|
51
51
|
return bs58.encode(this.toBuffer())
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Return the byte array representation of the public key in big endian
|
|
56
|
+
*/
|
|
57
|
+
toBytes() {
|
|
58
|
+
const buf = this.toBuffer()
|
|
59
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength)
|
|
60
|
+
}
|
|
61
|
+
|
|
54
62
|
/**
|
|
55
63
|
* Return the Buffer representation of the public key
|
|
56
64
|
*/
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { Transaction, VersionedTransaction } from '..'
|
|
2
|
-
import { SUPPORTED_TRANSACTION_VERSIONS } from '../constants'
|
|
3
|
-
|
|
4
|
-
const isVersionedTransactionType = (transaction) => {
|
|
5
|
-
// new transaction types have a version field, either a string(legacy) or a number(>=0)
|
|
6
|
-
return transaction.version !== undefined
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const isVersionedTransactionTypeSupported = (transaction) => {
|
|
10
|
-
return SUPPORTED_TRANSACTION_VERSIONS.has(transaction.version)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const getTransactionStrategy = (transaction) => {
|
|
14
|
-
if (isVersionedTransactionType(transaction)) {
|
|
15
|
-
if (isVersionedTransactionTypeSupported(transaction)) {
|
|
16
|
-
return VersionedTransaction
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
throw new Error(`unsupported transaction version: ${transaction.version}`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return Transaction
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export default getTransactionStrategy
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import base58 from 'bs58'
|
|
2
|
-
import { getKeyPairFromPrivateKey } from './keypair'
|
|
3
|
-
import { Account } from './vendor'
|
|
4
|
-
|
|
5
|
-
function getFirstSignature(tx) {
|
|
6
|
-
if (tx.signatures.length > 0) {
|
|
7
|
-
return tx.signatures[0]
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return null
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
class VersionedTx {
|
|
14
|
-
// tx is not supported from the vendored library (solana-lib/src/vendor).
|
|
15
|
-
// We also can't make any guarantees that Account from vendored lib with version X
|
|
16
|
-
// will be compatible with the tx built by an outside library with version Y.
|
|
17
|
-
static sign(tx, privateKey, extraSigners = []) {
|
|
18
|
-
if (!privateKey) {
|
|
19
|
-
throw new Error('Please provide a secretKey')
|
|
20
|
-
}
|
|
21
|
-
const { secretKey } = getKeyPairFromPrivateKey(privateKey)
|
|
22
|
-
const signers = [new Account(secretKey), ...extraSigners]
|
|
23
|
-
|
|
24
|
-
tx.sign(signers)
|
|
25
|
-
|
|
26
|
-
if (!(tx.signatures && tx.signatures.length)) {
|
|
27
|
-
throw new Error('!Signature')
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
static serialize(tx) {
|
|
32
|
-
const serializedTx = tx.serialize()
|
|
33
|
-
return Buffer.from(serializedTx).toString('base64')
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
static getTxId(tx) {
|
|
37
|
-
const signature = getFirstSignature(tx)
|
|
38
|
-
if (signature === null) {
|
|
39
|
-
throw new Error('Cannot get transaction ID of unsigned transaction')
|
|
40
|
-
}
|
|
41
|
-
return base58.encode(signature)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export default VersionedTx
|