@exodus/solana-lib 1.3.2 → 1.3.3
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 +3 -2
- package/src/transaction.js +28 -5
- package/src/tx/create-unsigned-tx.js +8 -2
- package/src/tx/index.js +1 -0
- package/src/tx/sign-message.js +11 -0
- package/src/tx/sign-unsigned-tx.js +5 -0
- package/src/vendor/transaction.js +35 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/solana-lib",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "Exodus internal Solana low-level library",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -24,5 +24,6 @@
|
|
|
24
24
|
"create-hash": "^1.1.3",
|
|
25
25
|
"lodash": "^4.17.11",
|
|
26
26
|
"tweetnacl": "^1.0.3"
|
|
27
|
-
}
|
|
27
|
+
},
|
|
28
|
+
"gitHead": "e0c7ce8b006cb8cfc78bbd86769b7b5b1890e72b"
|
|
28
29
|
}
|
package/src/transaction.js
CHANGED
|
@@ -36,11 +36,15 @@ class Tx {
|
|
|
36
36
|
destinationAddressType,
|
|
37
37
|
isAssociatedTokenAccountActive, // true when recipient balance !== 0
|
|
38
38
|
fromTokenAddresses, // sender token addresses
|
|
39
|
+
instructions,
|
|
40
|
+
feePayer,
|
|
39
41
|
} = {}) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
if (!instructions) {
|
|
43
|
+
assert(from, 'from is required')
|
|
44
|
+
assert(to, 'to is required')
|
|
45
|
+
assert(amount, 'amount is required')
|
|
46
|
+
assert(typeof amount === 'number', 'amount must be a number')
|
|
47
|
+
}
|
|
44
48
|
assert(recentBlockhash, 'recentBlockhash is required')
|
|
45
49
|
if (tokenMintAddress) {
|
|
46
50
|
assert(
|
|
@@ -63,11 +67,15 @@ class Tx {
|
|
|
63
67
|
destinationAddressType,
|
|
64
68
|
isAssociatedTokenAccountActive,
|
|
65
69
|
fromTokenAddresses,
|
|
70
|
+
instructions,
|
|
71
|
+
feePayer,
|
|
66
72
|
}
|
|
67
73
|
|
|
68
74
|
if (tokenMintAddress) {
|
|
69
75
|
// TOKEN transfer tx
|
|
70
76
|
this.buildTokenTransaction(this.txObj)
|
|
77
|
+
} else if (instructions) {
|
|
78
|
+
this.buildInstructionsTransaction(this.txObj)
|
|
71
79
|
} else {
|
|
72
80
|
// SOL tx
|
|
73
81
|
this.buildSOLtransaction(this.txObj)
|
|
@@ -87,6 +95,21 @@ class Tx {
|
|
|
87
95
|
})
|
|
88
96
|
}
|
|
89
97
|
|
|
98
|
+
buildInstructionsTransaction({ feePayer, recentBlockhash, instructions }) {
|
|
99
|
+
this.transaction = new Transaction({
|
|
100
|
+
feePayer: new PublicKey(feePayer),
|
|
101
|
+
instructions: instructions.map(i => ({
|
|
102
|
+
programId: new PublicKey(i.programId),
|
|
103
|
+
data: i.data ? Buffer.from(i.data) : Buffer.from([]),
|
|
104
|
+
keys: i.keys.map(k => ({
|
|
105
|
+
...k,
|
|
106
|
+
pubkey: new PublicKey(k.pubkey)
|
|
107
|
+
}))
|
|
108
|
+
})),
|
|
109
|
+
recentBlockhash,
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
90
113
|
buildTokenTransaction({
|
|
91
114
|
from,
|
|
92
115
|
to,
|
|
@@ -325,7 +348,7 @@ class Tx {
|
|
|
325
348
|
|
|
326
349
|
const info = {
|
|
327
350
|
txId,
|
|
328
|
-
owner: tx.
|
|
351
|
+
owner: tx.getFeePayer().toString(), // SOL sender
|
|
329
352
|
}
|
|
330
353
|
const txDetails = stakingInstructions.reduce((info, ix) => {
|
|
331
354
|
const type = StakeInstruction.decodeInstructionType(ix)
|
|
@@ -30,13 +30,16 @@ export function createUnsignedTx({
|
|
|
30
30
|
expectedMintAddress,
|
|
31
31
|
metadataAddress,
|
|
32
32
|
creators,
|
|
33
|
+
// Wallet Connect
|
|
34
|
+
instructions,
|
|
35
|
+
feePayer,
|
|
33
36
|
}: ParsedTransaction): UnsignedTransaction {
|
|
34
37
|
return {
|
|
35
38
|
txData: {
|
|
36
39
|
from,
|
|
37
40
|
to,
|
|
38
|
-
amount: amount.toBase().toNumber(),
|
|
39
|
-
fee: fee.toBase().toNumber(),
|
|
41
|
+
amount: amount ? amount.toBase().toNumber() : null,
|
|
42
|
+
fee: fee ? fee.toBase().toNumber() : null,
|
|
40
43
|
recentBlockhash,
|
|
41
44
|
// Tokens related:
|
|
42
45
|
tokenMintAddress,
|
|
@@ -60,6 +63,9 @@ export function createUnsignedTx({
|
|
|
60
63
|
takerAddress,
|
|
61
64
|
metadataAddress,
|
|
62
65
|
creators,
|
|
66
|
+
// Wallet Connect
|
|
67
|
+
instructions,
|
|
68
|
+
feePayer,
|
|
63
69
|
},
|
|
64
70
|
txMeta: {
|
|
65
71
|
assetName: asset.name,
|
package/src/tx/index.js
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import nacl from 'tweetnacl'
|
|
2
|
+
import bs58 from 'bs58'
|
|
3
|
+
|
|
4
|
+
import { getKeyPairFromPrivateKey } from '../keypair'
|
|
5
|
+
|
|
6
|
+
export default function signMessage({ message, privateKey }) {
|
|
7
|
+
const { secretKey } = getKeyPairFromPrivateKey(privateKey)
|
|
8
|
+
const signature = nacl.sign.detached(bs58.decode(message), secretKey)
|
|
9
|
+
const bs58Signature = bs58.encode(signature)
|
|
10
|
+
return bs58Signature
|
|
11
|
+
}
|
|
@@ -33,6 +33,9 @@ export function signUnsignedTx(
|
|
|
33
33
|
expectedMintAddress,
|
|
34
34
|
metadataAddress,
|
|
35
35
|
creators,
|
|
36
|
+
// Wallet Connect
|
|
37
|
+
instructions,
|
|
38
|
+
feePayer,
|
|
36
39
|
} = unsignedTx.txData
|
|
37
40
|
|
|
38
41
|
const asset = assets.solana
|
|
@@ -112,6 +115,8 @@ export function signUnsignedTx(
|
|
|
112
115
|
destinationAddressType,
|
|
113
116
|
isAssociatedTokenAccountActive,
|
|
114
117
|
fromTokenAddresses,
|
|
118
|
+
instructions,
|
|
119
|
+
feePayer,
|
|
115
120
|
})
|
|
116
121
|
break
|
|
117
122
|
}
|
|
@@ -152,15 +152,22 @@ export class Transaction {
|
|
|
152
152
|
}
|
|
153
153
|
return null
|
|
154
154
|
}
|
|
155
|
+
|
|
155
156
|
/**
|
|
157
|
+
* The transaction fee payer
|
|
158
|
+
*/
|
|
159
|
+
feePayer: PublicKey;
|
|
160
|
+
|
|
161
|
+
/**
|
|
156
162
|
* The transaction fee payer (first signer)
|
|
157
163
|
*/
|
|
158
|
-
|
|
164
|
+
getFeePayer(): PublicKey | null {
|
|
159
165
|
if (this.signatures.length > 0) {
|
|
160
166
|
return this.signatures[0].publicKey
|
|
161
167
|
}
|
|
162
168
|
return null
|
|
163
169
|
}
|
|
170
|
+
|
|
164
171
|
/**
|
|
165
172
|
* The instructions to atomically execute
|
|
166
173
|
*/
|
|
@@ -222,8 +229,14 @@ export class Transaction {
|
|
|
222
229
|
throw new Error('No instructions provided')
|
|
223
230
|
}
|
|
224
231
|
|
|
225
|
-
|
|
226
|
-
|
|
232
|
+
let feePayer: PublicKey;
|
|
233
|
+
if (this.feePayer) {
|
|
234
|
+
feePayer = this.feePayer;
|
|
235
|
+
} else if (this.signatures.length > 0 && this.signatures[0].publicKey) {
|
|
236
|
+
// Use implicit fee payer
|
|
237
|
+
feePayer = this.signatures[0].publicKey;
|
|
238
|
+
} else {
|
|
239
|
+
throw new Error('Transaction fee payer required');
|
|
227
240
|
}
|
|
228
241
|
|
|
229
242
|
const programIds: string[] = []
|
|
@@ -268,6 +281,25 @@ export class Transaction {
|
|
|
268
281
|
uniqueMetas.push(accountMeta)
|
|
269
282
|
}
|
|
270
283
|
})
|
|
284
|
+
|
|
285
|
+
const feePayerIndex = uniqueMetas.findIndex(x => {
|
|
286
|
+
return x.pubkey.equals(feePayer);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
if (feePayerIndex > -1) {
|
|
290
|
+
const [payerMeta] = uniqueMetas.splice(feePayerIndex, 1);
|
|
291
|
+
payerMeta.isSigner = true;
|
|
292
|
+
payerMeta.isWritable = true;
|
|
293
|
+
uniqueMetas.unshift(payerMeta);
|
|
294
|
+
} else {
|
|
295
|
+
uniqueMetas.unshift({
|
|
296
|
+
pubkey: feePayer,
|
|
297
|
+
isSigner: true,
|
|
298
|
+
isWritable: true
|
|
299
|
+
});
|
|
300
|
+
} // Disallow unknown signers
|
|
301
|
+
|
|
302
|
+
|
|
271
303
|
// Move payer to the front and disallow unknown signers
|
|
272
304
|
this.signatures.forEach((signature, signatureIndex) => {
|
|
273
305
|
const isPayer = signatureIndex === 0
|