@exodus/solana-lib 1.2.9-build → 1.2.9
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 -3
- package/src/constants.js +12 -0
- package/src/encode.js +57 -0
- package/src/fee-data/index.js +1 -0
- package/src/fee-data/solana.js +9 -0
- package/src/helpers/spl-token.js +108 -0
- package/src/helpers/tokenTransfer.js +72 -0
- package/src/index.js +8 -0
- package/src/keypair.js +32 -0
- package/src/tokens.js +19 -0
- package/src/transaction.js +240 -0
- package/src/tx/create-and-sign-tx.js +8 -0
- package/{lib → src}/tx/create-unsigned-tx.js +11 -18
- package/src/tx/index.js +4 -0
- package/src/tx/parse-unsigned-tx.js +41 -0
- package/src/tx/sign-unsigned-tx.js +78 -0
- package/src/vendor/account.js +38 -0
- package/src/vendor/index.js +9 -0
- package/src/vendor/instruction.js +46 -0
- package/src/vendor/message.js +216 -0
- package/src/vendor/nonce-account.js +46 -0
- package/src/vendor/publickey.js +212 -0
- package/src/vendor/stake-program.js +527 -0
- package/src/vendor/system-program.js +782 -0
- package/src/vendor/sysvar.js +16 -0
- package/src/vendor/transaction.js +594 -0
- package/src/vendor/utils/blockhash.js +6 -0
- package/src/vendor/utils/fee-calculator.js +17 -0
- package/src/vendor/utils/layout.js +80 -0
- package/src/vendor/utils/shortvec-encoding.js +30 -0
- package/src/vendor/utils/to-buffer.js +9 -0
- package/lib/constants.js +0 -19
- package/lib/encode.js +0 -67
- package/lib/fee-data/index.js +0 -15
- package/lib/fee-data/solana.js +0 -14
- package/lib/helpers/spl-token.js +0 -122
- package/lib/helpers/tokenTransfer.js +0 -78
- package/lib/index.js +0 -79
- package/lib/keypair.js +0 -38
- package/lib/tokens.js +0 -21
- package/lib/transaction.js +0 -279
- package/lib/tx/create-and-sign-tx.js +0 -15
- package/lib/tx/index.js +0 -53
- package/lib/tx/parse-unsigned-tx.js +0 -55
- package/lib/tx/sign-unsigned-tx.js +0 -90
- package/lib/vendor/account.js +0 -48
- package/lib/vendor/index.js +0 -113
- package/lib/vendor/instruction.js +0 -48
- package/lib/vendor/message.js +0 -167
- package/lib/vendor/nonce-account.js +0 -56
- package/lib/vendor/publickey.js +0 -211
- package/lib/vendor/stake-program.js +0 -476
- package/lib/vendor/system-program.js +0 -640
- package/lib/vendor/sysvar.js +0 -19
- package/lib/vendor/transaction.js +0 -594
- package/lib/vendor/utils/blockhash.js +0 -1
- package/lib/vendor/utils/fee-calculator.js +0 -25
- package/lib/vendor/utils/layout.js +0 -97
- package/lib/vendor/utils/shortvec-encoding.js +0 -41
- package/lib/vendor/utils/to-buffer.js +0 -18
|
@@ -1,594 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.Transaction = exports.TransactionInstruction = exports.PACKET_DATA_SIZE = void 0;
|
|
7
|
-
|
|
8
|
-
var _assert = _interopRequireDefault(require("assert"));
|
|
9
|
-
|
|
10
|
-
var _tweetnacl = _interopRequireDefault(require("tweetnacl"));
|
|
11
|
-
|
|
12
|
-
var _bs = _interopRequireDefault(require("bs58"));
|
|
13
|
-
|
|
14
|
-
var _message = require("./message");
|
|
15
|
-
|
|
16
|
-
var _index = require("./index");
|
|
17
|
-
|
|
18
|
-
var shortvec = _interopRequireWildcard(require("./utils/shortvec-encoding"));
|
|
19
|
-
|
|
20
|
-
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
21
|
-
|
|
22
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
23
|
-
|
|
24
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
|
-
|
|
26
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
27
|
-
|
|
28
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
29
|
-
|
|
30
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Default (empty) signature
|
|
34
|
-
*
|
|
35
|
-
* Signatures are 64 bytes in length
|
|
36
|
-
*/
|
|
37
|
-
const DEFAULT_SIGNATURE = Buffer.alloc(64).fill(0);
|
|
38
|
-
/**
|
|
39
|
-
* Maximum over-the-wire size of a Transaction
|
|
40
|
-
*
|
|
41
|
-
* 1280 is IPv6 minimum MTU
|
|
42
|
-
* 40 bytes is the size of the IPv6 header
|
|
43
|
-
* 8 bytes is the size of the fragment header
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
const PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
47
|
-
exports.PACKET_DATA_SIZE = PACKET_DATA_SIZE;
|
|
48
|
-
const SIGNATURE_LENGTH = 64;
|
|
49
|
-
/**
|
|
50
|
-
* Account metadata used to define instructions
|
|
51
|
-
*
|
|
52
|
-
* @typedef {Object} AccountMeta
|
|
53
|
-
* @property {PublicKey} pubkey An account's public key
|
|
54
|
-
* @property {boolean} isSigner True if an instruction requires a transaction signature matching `pubkey`
|
|
55
|
-
* @property {boolean} isWritable True if the `pubkey` can be loaded as a read-write account.
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Transaction Instruction class
|
|
60
|
-
*/
|
|
61
|
-
class TransactionInstruction {
|
|
62
|
-
/**
|
|
63
|
-
* Public keys to include in this transaction
|
|
64
|
-
* Boolean represents whether this pubkey needs to sign the transaction
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Program Id to execute
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Program input
|
|
73
|
-
*/
|
|
74
|
-
constructor(opts) {
|
|
75
|
-
_defineProperty(this, "keys", []);
|
|
76
|
-
|
|
77
|
-
_defineProperty(this, "programId", void 0);
|
|
78
|
-
|
|
79
|
-
_defineProperty(this, "data", Buffer.alloc(0));
|
|
80
|
-
|
|
81
|
-
opts && Object.assign(this, opts);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* @private
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
exports.TransactionInstruction = TransactionInstruction;
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Transaction class
|
|
94
|
-
*/
|
|
95
|
-
class Transaction {
|
|
96
|
-
/**
|
|
97
|
-
* Signatures for the transaction. Typically created by invoking the
|
|
98
|
-
* `sign()` method
|
|
99
|
-
*/
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* The first (payer) Transaction signature
|
|
103
|
-
*/
|
|
104
|
-
get signature() {
|
|
105
|
-
if (this.signatures.length > 0) {
|
|
106
|
-
return this.signatures[0].signature;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* The transaction fee payer (first signer)
|
|
113
|
-
*/
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
get feePayer() {
|
|
117
|
-
if (this.signatures.length > 0) {
|
|
118
|
-
return this.signatures[0].publicKey;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* The instructions to atomically execute
|
|
125
|
-
*/
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Construct an empty Transaction
|
|
130
|
-
*/
|
|
131
|
-
constructor(opts) {
|
|
132
|
-
_defineProperty(this, "signatures", []);
|
|
133
|
-
|
|
134
|
-
_defineProperty(this, "instructions", []);
|
|
135
|
-
|
|
136
|
-
_defineProperty(this, "recentBlockhash", void 0);
|
|
137
|
-
|
|
138
|
-
_defineProperty(this, "nonceInfo", void 0);
|
|
139
|
-
|
|
140
|
-
opts && Object.assign(this, opts);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Add one or more instructions to this Transaction
|
|
144
|
-
*/
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
add(...items) {
|
|
148
|
-
if (items.length === 0) {
|
|
149
|
-
throw new Error('No instructions');
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
items.forEach(item => {
|
|
153
|
-
if ('instructions' in item) {
|
|
154
|
-
this.instructions = this.instructions.concat(item.instructions);
|
|
155
|
-
} else if ('data' in item && 'programId' in item && 'keys' in item) {
|
|
156
|
-
this.instructions.push(item);
|
|
157
|
-
} else {
|
|
158
|
-
this.instructions.push(new TransactionInstruction(item));
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
return this;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Compile transaction data
|
|
165
|
-
*/
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
compileMessage() {
|
|
169
|
-
const {
|
|
170
|
-
nonceInfo
|
|
171
|
-
} = this;
|
|
172
|
-
|
|
173
|
-
if (nonceInfo && this.instructions[0] !== nonceInfo.nonceInstruction) {
|
|
174
|
-
this.recentBlockhash = nonceInfo.nonce;
|
|
175
|
-
this.instructions.unshift(nonceInfo.nonceInstruction);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const {
|
|
179
|
-
recentBlockhash
|
|
180
|
-
} = this;
|
|
181
|
-
|
|
182
|
-
if (!recentBlockhash) {
|
|
183
|
-
throw new Error('Transaction recentBlockhash required');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (this.instructions.length < 1) {
|
|
187
|
-
throw new Error('No instructions provided');
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (this.feePayer === null) {
|
|
191
|
-
throw new Error('Transaction feePayer required');
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const programIds = [];
|
|
195
|
-
const accountMetas = [];
|
|
196
|
-
this.instructions.forEach(instruction => {
|
|
197
|
-
instruction.keys.forEach(accountMeta => {
|
|
198
|
-
accountMetas.push(_objectSpread({}, accountMeta));
|
|
199
|
-
});
|
|
200
|
-
const programId = instruction.programId.toString();
|
|
201
|
-
|
|
202
|
-
if (!programIds.includes(programId)) {
|
|
203
|
-
programIds.push(programId);
|
|
204
|
-
}
|
|
205
|
-
}); // Append programID account metas
|
|
206
|
-
|
|
207
|
-
programIds.forEach(programId => {
|
|
208
|
-
accountMetas.push({
|
|
209
|
-
pubkey: new _index.PublicKey(programId),
|
|
210
|
-
isSigner: false,
|
|
211
|
-
isWritable: false
|
|
212
|
-
});
|
|
213
|
-
}); // Sort. Prioritizing first by signer, then by writable
|
|
214
|
-
|
|
215
|
-
accountMetas.sort(function (x, y) {
|
|
216
|
-
const checkSigner = x.isSigner === y.isSigner ? 0 : x.isSigner ? -1 : 1;
|
|
217
|
-
const checkWritable = x.isWritable === y.isWritable ? 0 : x.isWritable ? -1 : 1;
|
|
218
|
-
return checkSigner || checkWritable;
|
|
219
|
-
}); // Cull duplicate account metas
|
|
220
|
-
|
|
221
|
-
const uniqueMetas = [];
|
|
222
|
-
accountMetas.forEach(accountMeta => {
|
|
223
|
-
const pubkeyString = accountMeta.pubkey.toString();
|
|
224
|
-
const uniqueIndex = uniqueMetas.findIndex(x => {
|
|
225
|
-
return x.pubkey.toString() === pubkeyString;
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
if (uniqueIndex > -1) {
|
|
229
|
-
uniqueMetas[uniqueIndex].isWritable = uniqueMetas[uniqueIndex].isWritable || accountMeta.isWritable;
|
|
230
|
-
} else {
|
|
231
|
-
uniqueMetas.push(accountMeta);
|
|
232
|
-
}
|
|
233
|
-
}); // Move payer to the front and disallow unknown signers
|
|
234
|
-
|
|
235
|
-
this.signatures.forEach((signature, signatureIndex) => {
|
|
236
|
-
const isPayer = signatureIndex === 0;
|
|
237
|
-
const uniqueIndex = uniqueMetas.findIndex(x => {
|
|
238
|
-
return x.pubkey.equals(signature.publicKey);
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
if (uniqueIndex > -1) {
|
|
242
|
-
if (isPayer) {
|
|
243
|
-
const [payerMeta] = uniqueMetas.splice(uniqueIndex, 1);
|
|
244
|
-
payerMeta.isSigner = true;
|
|
245
|
-
payerMeta.isWritable = true;
|
|
246
|
-
uniqueMetas.unshift(payerMeta);
|
|
247
|
-
} else {
|
|
248
|
-
uniqueMetas[uniqueIndex].isSigner = true;
|
|
249
|
-
}
|
|
250
|
-
} else if (isPayer) {
|
|
251
|
-
uniqueMetas.unshift({
|
|
252
|
-
pubkey: signature.publicKey,
|
|
253
|
-
isSigner: true,
|
|
254
|
-
isWritable: true
|
|
255
|
-
});
|
|
256
|
-
} else {
|
|
257
|
-
throw new Error(`unknown signer: ${signature.publicKey.toString()}`);
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
let numRequiredSignatures = 0;
|
|
261
|
-
let numReadonlySignedAccounts = 0;
|
|
262
|
-
let numReadonlyUnsignedAccounts = 0; // Split out signing from non-signing keys and count header values
|
|
263
|
-
|
|
264
|
-
const signedKeys = [];
|
|
265
|
-
const unsignedKeys = [];
|
|
266
|
-
uniqueMetas.forEach(({
|
|
267
|
-
pubkey,
|
|
268
|
-
isSigner,
|
|
269
|
-
isWritable
|
|
270
|
-
}) => {
|
|
271
|
-
if (isSigner) {
|
|
272
|
-
signedKeys.push(pubkey.toString());
|
|
273
|
-
numRequiredSignatures += 1;
|
|
274
|
-
|
|
275
|
-
if (!isWritable) {
|
|
276
|
-
numReadonlySignedAccounts += 1;
|
|
277
|
-
}
|
|
278
|
-
} else {
|
|
279
|
-
unsignedKeys.push(pubkey.toString());
|
|
280
|
-
|
|
281
|
-
if (!isWritable) {
|
|
282
|
-
numReadonlyUnsignedAccounts += 1;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
if (numRequiredSignatures !== this.signatures.length) {
|
|
288
|
-
throw new Error(`missing signer(s) - required signatures: ${numRequiredSignatures}, got ${this.signatures.length}`);
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const accountKeys = signedKeys.concat(unsignedKeys);
|
|
292
|
-
const instructions = this.instructions.map(instruction => {
|
|
293
|
-
const {
|
|
294
|
-
data,
|
|
295
|
-
programId
|
|
296
|
-
} = instruction;
|
|
297
|
-
return {
|
|
298
|
-
programIdIndex: accountKeys.indexOf(programId.toString()),
|
|
299
|
-
accounts: instruction.keys.map(keyObj => accountKeys.indexOf(keyObj.pubkey.toString())),
|
|
300
|
-
data: _bs.default.encode(data)
|
|
301
|
-
};
|
|
302
|
-
});
|
|
303
|
-
instructions.forEach(instruction => {
|
|
304
|
-
(0, _assert.default)(instruction.programIdIndex >= 0);
|
|
305
|
-
instruction.accounts.forEach(keyIndex => (0, _assert.default)(keyIndex >= 0));
|
|
306
|
-
});
|
|
307
|
-
return new _message.Message({
|
|
308
|
-
header: {
|
|
309
|
-
numRequiredSignatures,
|
|
310
|
-
numReadonlySignedAccounts,
|
|
311
|
-
numReadonlyUnsignedAccounts
|
|
312
|
-
},
|
|
313
|
-
accountKeys,
|
|
314
|
-
recentBlockhash,
|
|
315
|
-
instructions
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Get a buffer of the Transaction data that need to be covered by signatures
|
|
320
|
-
*/
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
serializeMessage() {
|
|
324
|
-
return this.compileMessage().serialize();
|
|
325
|
-
}
|
|
326
|
-
/**
|
|
327
|
-
* Specify the public keys which will be used to sign the Transaction.
|
|
328
|
-
* The first signer will be used as the transaction fee payer account.
|
|
329
|
-
*
|
|
330
|
-
* Signatures can be added with either `partialSign` or `addSignature`
|
|
331
|
-
*/
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
setSigners(...signers) {
|
|
335
|
-
if (signers.length === 0) {
|
|
336
|
-
throw new Error('No signers');
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
const seen = new Set();
|
|
340
|
-
this.signatures = signers.filter(publicKey => {
|
|
341
|
-
const key = publicKey.toString();
|
|
342
|
-
|
|
343
|
-
if (seen.has(key)) {
|
|
344
|
-
return false;
|
|
345
|
-
} else {
|
|
346
|
-
seen.add(key);
|
|
347
|
-
return true;
|
|
348
|
-
}
|
|
349
|
-
}).map(publicKey => ({
|
|
350
|
-
signature: null,
|
|
351
|
-
publicKey
|
|
352
|
-
}));
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Sign the Transaction with the specified accounts. Multiple signatures may
|
|
356
|
-
* be applied to a Transaction. The first signature is considered "primary"
|
|
357
|
-
* and is used when testing for Transaction confirmation. The first signer
|
|
358
|
-
* will be used as the transaction fee payer account.
|
|
359
|
-
*
|
|
360
|
-
* Transaction fields should not be modified after the first call to `sign`,
|
|
361
|
-
* as doing so may invalidate the signature and cause the Transaction to be
|
|
362
|
-
* rejected.
|
|
363
|
-
*
|
|
364
|
-
* The Transaction must be assigned a valid `recentBlockhash` before invoking this method
|
|
365
|
-
*/
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
sign(...signers) {
|
|
369
|
-
if (signers.length === 0) {
|
|
370
|
-
throw new Error('No signers');
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const seen = new Set();
|
|
374
|
-
this.signatures = signers.filter(signer => {
|
|
375
|
-
const key = signer.publicKey.toString();
|
|
376
|
-
|
|
377
|
-
if (seen.has(key)) {
|
|
378
|
-
return false;
|
|
379
|
-
} else {
|
|
380
|
-
seen.add(key);
|
|
381
|
-
return true;
|
|
382
|
-
}
|
|
383
|
-
}).map(signer => ({
|
|
384
|
-
signature: null,
|
|
385
|
-
publicKey: signer.publicKey
|
|
386
|
-
}));
|
|
387
|
-
this.partialSign(...signers);
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Partially sign a transaction with the specified accounts. All accounts must
|
|
391
|
-
* correspond to a public key that was previously provided to `setSigners`.
|
|
392
|
-
*
|
|
393
|
-
* All the caveats from the `sign` method apply to `partialSign`
|
|
394
|
-
*/
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
partialSign(...signers) {
|
|
398
|
-
if (signers.length === 0) {
|
|
399
|
-
throw new Error('No signers');
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
const message = this.compileMessage();
|
|
403
|
-
this.signatures.sort(function (x, y) {
|
|
404
|
-
const xIndex = message.findSignerIndex(x.publicKey);
|
|
405
|
-
const yIndex = message.findSignerIndex(y.publicKey);
|
|
406
|
-
return xIndex < yIndex ? -1 : 1;
|
|
407
|
-
});
|
|
408
|
-
const signData = message.serialize();
|
|
409
|
-
signers.forEach(signer => {
|
|
410
|
-
const signature = _tweetnacl.default.sign.detached(signData, signer.secretKey);
|
|
411
|
-
|
|
412
|
-
this.addSignature(signer.publicKey, signature);
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
/**
|
|
416
|
-
* Add an externally created signature to a transaction. The public key
|
|
417
|
-
* must correspond to a public key that was previously provided to `setSigners`.
|
|
418
|
-
*/
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
addSignature(pubkey, signature) {
|
|
422
|
-
(0, _assert.default)(signature.length === 64);
|
|
423
|
-
const index = this.signatures.findIndex(sigpair => pubkey.equals(sigpair.publicKey));
|
|
424
|
-
|
|
425
|
-
if (index < 0) {
|
|
426
|
-
throw new Error(`unknown signer: ${pubkey.toString()}`);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
this.signatures[index].signature = Buffer.from(signature);
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Verify signatures of a complete, signed Transaction
|
|
433
|
-
*/
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
verifySignatures() {
|
|
437
|
-
return this._verifySignatures(this.serializeMessage(), true);
|
|
438
|
-
}
|
|
439
|
-
/**
|
|
440
|
-
* @private
|
|
441
|
-
*/
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
_verifySignatures(signData, requireAllSignatures) {
|
|
445
|
-
for (const {
|
|
446
|
-
signature,
|
|
447
|
-
publicKey
|
|
448
|
-
} of this.signatures) {
|
|
449
|
-
if (signature === null) {
|
|
450
|
-
if (requireAllSignatures) {
|
|
451
|
-
return false;
|
|
452
|
-
}
|
|
453
|
-
} else {
|
|
454
|
-
if (!_tweetnacl.default.sign.detached.verify(signData, signature, publicKey.toBuffer())) {
|
|
455
|
-
return false;
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
return true;
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* Serialize the Transaction in the wire format.
|
|
464
|
-
*/
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
serialize(config) {
|
|
468
|
-
const {
|
|
469
|
-
requireAllSignatures,
|
|
470
|
-
verifySignatures
|
|
471
|
-
} = Object.assign({
|
|
472
|
-
requireAllSignatures: true,
|
|
473
|
-
verifySignatures: true
|
|
474
|
-
}, config);
|
|
475
|
-
const signData = this.serializeMessage();
|
|
476
|
-
|
|
477
|
-
if (verifySignatures && !this._verifySignatures(signData, requireAllSignatures)) {
|
|
478
|
-
throw new Error('Signature verification failed');
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
return this._serialize(signData);
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* @private
|
|
485
|
-
*/
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
_serialize(signData) {
|
|
489
|
-
const {
|
|
490
|
-
signatures
|
|
491
|
-
} = this;
|
|
492
|
-
const signatureCount = [];
|
|
493
|
-
shortvec.encodeLength(signatureCount, signatures.length);
|
|
494
|
-
const transactionLength = signatureCount.length + signatures.length * 64 + signData.length;
|
|
495
|
-
const wireTransaction = Buffer.alloc(transactionLength);
|
|
496
|
-
(0, _assert.default)(signatures.length < 256);
|
|
497
|
-
Buffer.from(signatureCount).copy(wireTransaction, 0);
|
|
498
|
-
signatures.forEach(({
|
|
499
|
-
signature
|
|
500
|
-
}, index) => {
|
|
501
|
-
if (signature !== null) {
|
|
502
|
-
(0, _assert.default)(signature.length === 64, `signature has invalid length`);
|
|
503
|
-
Buffer.from(signature).copy(wireTransaction, signatureCount.length + index * 64);
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
signData.copy(wireTransaction, signatureCount.length + signatures.length * 64);
|
|
507
|
-
(0, _assert.default)(wireTransaction.length <= PACKET_DATA_SIZE, `Transaction too large: ${wireTransaction.length} > ${PACKET_DATA_SIZE}`);
|
|
508
|
-
return wireTransaction;
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Deprecated method
|
|
512
|
-
* @private
|
|
513
|
-
*/
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
get keys() {
|
|
517
|
-
(0, _assert.default)(this.instructions.length === 1);
|
|
518
|
-
return this.instructions[0].keys.map(keyObj => keyObj.pubkey);
|
|
519
|
-
}
|
|
520
|
-
/**
|
|
521
|
-
* Deprecated method
|
|
522
|
-
* @private
|
|
523
|
-
*/
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
get programId() {
|
|
527
|
-
(0, _assert.default)(this.instructions.length === 1);
|
|
528
|
-
return this.instructions[0].programId;
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* Deprecated method
|
|
532
|
-
* @private
|
|
533
|
-
*/
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
get data() {
|
|
537
|
-
(0, _assert.default)(this.instructions.length === 1);
|
|
538
|
-
return this.instructions[0].data;
|
|
539
|
-
}
|
|
540
|
-
/**
|
|
541
|
-
* Parse a wire transaction into a Transaction object.
|
|
542
|
-
*/
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
static from(buffer) {
|
|
546
|
-
// Slice up wire data
|
|
547
|
-
let byteArray = [...buffer];
|
|
548
|
-
const signatureCount = shortvec.decodeLength(byteArray);
|
|
549
|
-
let signatures = [];
|
|
550
|
-
|
|
551
|
-
for (let i = 0; i < signatureCount; i++) {
|
|
552
|
-
const signature = byteArray.slice(0, SIGNATURE_LENGTH);
|
|
553
|
-
byteArray = byteArray.slice(SIGNATURE_LENGTH);
|
|
554
|
-
signatures.push(_bs.default.encode(Buffer.from(signature)));
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
return Transaction.populate(_message.Message.from(byteArray), signatures);
|
|
558
|
-
}
|
|
559
|
-
/**
|
|
560
|
-
* Populate Transaction object from message and signatures
|
|
561
|
-
*/
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
static populate(message, signatures) {
|
|
565
|
-
const transaction = new Transaction();
|
|
566
|
-
transaction.recentBlockhash = message.recentBlockhash;
|
|
567
|
-
signatures.forEach((signature, index) => {
|
|
568
|
-
const sigPubkeyPair = {
|
|
569
|
-
signature: signature === _bs.default.encode(DEFAULT_SIGNATURE) ? null : _bs.default.decode(signature),
|
|
570
|
-
publicKey: message.accountKeys[index]
|
|
571
|
-
};
|
|
572
|
-
transaction.signatures.push(sigPubkeyPair);
|
|
573
|
-
});
|
|
574
|
-
message.instructions.forEach(instruction => {
|
|
575
|
-
const keys = instruction.accounts.map(account => {
|
|
576
|
-
const pubkey = message.accountKeys[account];
|
|
577
|
-
return {
|
|
578
|
-
pubkey,
|
|
579
|
-
isSigner: transaction.signatures.some(keyObj => keyObj.publicKey.toString() === pubkey.toString()),
|
|
580
|
-
isWritable: message.isAccountWritable(account)
|
|
581
|
-
};
|
|
582
|
-
});
|
|
583
|
-
transaction.instructions.push(new TransactionInstruction({
|
|
584
|
-
keys,
|
|
585
|
-
programId: message.accountKeys[instruction.programIdIndex],
|
|
586
|
-
data: _bs.default.decode(instruction.data)
|
|
587
|
-
}));
|
|
588
|
-
});
|
|
589
|
-
return transaction;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
exports.Transaction = Transaction;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.FeeCalculatorLayout = void 0;
|
|
7
|
-
|
|
8
|
-
var BufferLayout = _interopRequireWildcard(require("@exodus/buffer-layout"));
|
|
9
|
-
|
|
10
|
-
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
11
|
-
|
|
12
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* https://github.com/solana-labs/solana/blob/90bedd7e067b5b8f3ddbb45da00a4e9cabb22c62/sdk/src/fee_calculator.rs#L7-L11
|
|
16
|
-
*
|
|
17
|
-
* @private
|
|
18
|
-
*/
|
|
19
|
-
const FeeCalculatorLayout = BufferLayout.nu64('lamportsPerSignature');
|
|
20
|
-
/**
|
|
21
|
-
* @typedef {Object} FeeCalculator
|
|
22
|
-
* @property {number} lamportsPerSignature lamports Cost in lamports to validate a signature
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
exports.FeeCalculatorLayout = FeeCalculatorLayout;
|