@solana/signers
Advanced tools
Comparing version 2.0.0-experimental.3331786 to 2.0.0-experimental.0eb69ae
import { getAddressFromPublicKey, isAddress } from '@solana/addresses'; | ||
import { generateKeyPair, signBytes } from '@solana/keys'; | ||
import { partiallySignTransaction } from '@solana/transactions'; | ||
import { assertTransactionIsFullySigned, partiallySignTransaction } from '@solana/transactions'; | ||
// src/keypair-signer.ts | ||
// src/deduplicate-signers.ts | ||
function deduplicateSigners(signers) { | ||
const deduplicated = {}; | ||
signers.forEach((signer) => { | ||
if (!deduplicated[signer.address]) { | ||
deduplicated[signer.address] = signer; | ||
} | ||
}); | ||
return Object.values(deduplicated); | ||
} | ||
// src/account-signer-meta.ts | ||
function getSignersFromInstruction(instruction) { | ||
return deduplicateSigners( | ||
(instruction.accounts ?? []).flatMap((account) => "signer" in account ? account.signer : []) | ||
); | ||
} | ||
function getSignersFromTransaction(transaction) { | ||
return deduplicateSigners(transaction.instructions.flatMap(getSignersFromInstruction)); | ||
} | ||
// src/message-partial-signer.ts | ||
@@ -76,10 +95,11 @@ function isMessagePartialSigner(value) { | ||
} | ||
var o = globalThis.TextEncoder; | ||
// src/signable-message.ts | ||
function createSignableMessage(content, signatures = {}) { | ||
return Object.freeze({ | ||
content: typeof content === "string" ? new o().encode(content) : content, | ||
signatures: Object.freeze({ ...signatures }) | ||
}); | ||
// src/noop-signer.ts | ||
function createNoopSigner(address) { | ||
const out = { | ||
address, | ||
signMessages: async (messages) => messages.map(() => Object.freeze({})), | ||
signTransactions: async (transactions) => transactions.map(() => Object.freeze({})) | ||
}; | ||
return Object.freeze(out); | ||
} | ||
@@ -117,4 +137,106 @@ | ||
export { assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner }; | ||
// src/sign-transaction.ts | ||
async function partiallySignTransactionWithSigners(transaction, config = {}) { | ||
const signers = config.signers ?? []; | ||
const { partialSigners, modifyingSigners } = categorizeTransactionSigners( | ||
deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]), | ||
{ identifySendingSigner: false } | ||
); | ||
return signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config.abortSignal); | ||
} | ||
async function signTransactionWithSigners(transaction, config = {}) { | ||
const signedTransaction = await partiallySignTransactionWithSigners(transaction, config); | ||
assertTransactionIsFullySigned(signedTransaction); | ||
return signedTransaction; | ||
} | ||
async function signAndSendTransactionWithSigners(transaction, config = {}) { | ||
const signers = config.signers ?? []; | ||
const abortSignal = config.abortSignal; | ||
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( | ||
deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]) | ||
); | ||
abortSignal?.throwIfAborted(); | ||
const signedTransaction = await signModifyingAndPartialTransactionSigners( | ||
transaction, | ||
modifyingSigners, | ||
partialSigners, | ||
abortSignal | ||
); | ||
if (sendingSigner) { | ||
abortSignal?.throwIfAborted(); | ||
const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); | ||
return signature; | ||
} | ||
if (config.fallbackSender) { | ||
assertTransactionIsFullySigned(signedTransaction); | ||
return config.fallbackSender(signedTransaction); | ||
} | ||
throw new Error("No TransactionSendingSigner was identified and no fallback sender was provided."); | ||
} | ||
function categorizeTransactionSigners(signers, config = {}) { | ||
const identifySendingSigner = config.identifySendingSigner ?? true; | ||
const sendingSigner = identifySendingSigner ? identifyTransactionSendingSigner(signers) : null; | ||
const otherSigners = signers.filter( | ||
(signer) => signer !== sendingSigner && (isTransactionModifyingSigner(signer) || isTransactionPartialSigner(signer)) | ||
); | ||
const modifyingSigners = identifyTransactionModifyingSigners(otherSigners); | ||
const partialSigners = otherSigners.filter(isTransactionPartialSigner).filter((signer) => !modifyingSigners.includes(signer)); | ||
return Object.freeze({ modifyingSigners, partialSigners, sendingSigner }); | ||
} | ||
function identifyTransactionSendingSigner(signers) { | ||
const sendingSigners = signers.filter(isTransactionSendingSigner); | ||
if (sendingSigners.length === 0) | ||
return null; | ||
const sendingOnlySigners = sendingSigners.filter( | ||
(signer) => !isTransactionModifyingSigner(signer) && !isTransactionPartialSigner(signer) | ||
); | ||
if (sendingOnlySigners.length > 0) { | ||
return sendingOnlySigners[0]; | ||
} | ||
return sendingSigners[0]; | ||
} | ||
function identifyTransactionModifyingSigners(signers) { | ||
const modifyingSigners = signers.filter(isTransactionModifyingSigner); | ||
if (modifyingSigners.length === 0) | ||
return []; | ||
const nonPartialSigners = modifyingSigners.filter((signer) => !isTransactionPartialSigner(signer)); | ||
if (nonPartialSigners.length > 0) | ||
return nonPartialSigners; | ||
return [modifyingSigners[0]]; | ||
} | ||
async function signModifyingAndPartialTransactionSigners(transaction, modifyingSigners = [], partialSigners = [], abortSignal) { | ||
const modifiedTransaction = await modifyingSigners.reduce(async (transaction2, modifyingSigner) => { | ||
abortSignal?.throwIfAborted(); | ||
const [tx] = await modifyingSigner.modifyAndSignTransactions([await transaction2], { abortSignal }); | ||
return Object.freeze(tx); | ||
}, Promise.resolve(transaction)); | ||
abortSignal?.throwIfAborted(); | ||
const signatureDictionaries = await Promise.all( | ||
partialSigners.map(async (partialSigner) => { | ||
const [signatures] = await partialSigner.signTransactions([modifiedTransaction], { abortSignal }); | ||
return signatures; | ||
}) | ||
); | ||
const signedTransaction = { | ||
...modifiedTransaction, | ||
signatures: Object.freeze( | ||
signatureDictionaries.reduce((signatures, signatureDictionary) => { | ||
return { ...signatures, ...signatureDictionary }; | ||
}, modifiedTransaction.signatures ?? {}) | ||
) | ||
}; | ||
return Object.freeze(signedTransaction); | ||
} | ||
var o = globalThis.TextEncoder; | ||
// src/signable-message.ts | ||
function createSignableMessage(content, signatures = {}) { | ||
return Object.freeze({ | ||
content: typeof content === "string" ? new o().encode(content) : content, | ||
signatures: Object.freeze({ ...signatures }) | ||
}); | ||
} | ||
export { assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createNoopSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, getSignersFromInstruction, getSignersFromTransaction, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner, partiallySignTransactionWithSigners, signAndSendTransactionWithSigners, signTransactionWithSigners }; | ||
//# sourceMappingURL=out.js.map | ||
//# sourceMappingURL=index.browser.js.map |
@@ -5,2 +5,24 @@ this.globalThis = this.globalThis || {}; | ||
// src/deduplicate-signers.ts | ||
function deduplicateSigners(signers) { | ||
const deduplicated = {}; | ||
signers.forEach((signer) => { | ||
if (!deduplicated[signer.address]) { | ||
deduplicated[signer.address] = signer; | ||
} | ||
}); | ||
return Object.values(deduplicated); | ||
} | ||
// src/account-signer-meta.ts | ||
function getSignersFromInstruction(instruction) { | ||
var _a; | ||
return deduplicateSigners( | ||
((_a = instruction.accounts) != null ? _a : []).flatMap((account) => "signer" in account ? account.signer : []) | ||
); | ||
} | ||
function getSignersFromTransaction(transaction) { | ||
return deduplicateSigners(transaction.instructions.flatMap(getSignersFromInstruction)); | ||
} | ||
// ../codecs-core/dist/index.browser.js | ||
@@ -45,3 +67,3 @@ function assertByteArrayIsNotEmptyForCodec(codecDescription, bytes, offset = 0) { | ||
return { | ||
description: description ?? `fixed(${fixedBytes}, ${data.description})`, | ||
description: description != null ? description : `fixed(${fixedBytes}, ${data.description})`, | ||
fixedSize: fixedBytes, | ||
@@ -91,2 +113,3 @@ maxSize: fixedBytes | ||
function sharedNumberFactory(input) { | ||
var _a; | ||
let littleEndian; | ||
@@ -99,3 +122,3 @@ let defaultDescription = input.name; | ||
return { | ||
description: input.config.description ?? defaultDescription, | ||
description: (_a = input.config.description) != null ? _a : defaultDescription, | ||
fixedSize: input.size, | ||
@@ -137,27 +160,30 @@ littleEndian, | ||
function toArrayBuffer(bytes, offset, length) { | ||
const bytesOffset = bytes.byteOffset + (offset ?? 0); | ||
const bytesLength = length ?? bytes.byteLength; | ||
const bytesOffset = bytes.byteOffset + (offset != null ? offset : 0); | ||
const bytesLength = length != null ? length : bytes.byteLength; | ||
return bytes.buffer.slice(bytesOffset, bytesOffset + bytesLength); | ||
} | ||
var getShortU16Encoder = (config = {}) => ({ | ||
description: config.description ?? "shortU16", | ||
encode: (value) => { | ||
assertNumberIsBetweenForCodec("shortU16", 0, 65535, value); | ||
const bytes = [0]; | ||
for (let ii = 0; ; ii += 1) { | ||
const alignedValue = value >> ii * 7; | ||
if (alignedValue === 0) { | ||
break; | ||
var getShortU16Encoder = (config = {}) => { | ||
var _a; | ||
return { | ||
description: (_a = config.description) != null ? _a : "shortU16", | ||
encode: (value) => { | ||
assertNumberIsBetweenForCodec("shortU16", 0, 65535, value); | ||
const bytes = [0]; | ||
for (let ii = 0; ; ii += 1) { | ||
const alignedValue = value >> ii * 7; | ||
if (alignedValue === 0) { | ||
break; | ||
} | ||
const nextSevenBits = 127 & alignedValue; | ||
bytes[ii] = nextSevenBits; | ||
if (ii > 0) { | ||
bytes[ii - 1] |= 128; | ||
} | ||
} | ||
const nextSevenBits = 127 & alignedValue; | ||
bytes[ii] = nextSevenBits; | ||
if (ii > 0) { | ||
bytes[ii - 1] |= 128; | ||
} | ||
} | ||
return new Uint8Array(bytes); | ||
}, | ||
fixedSize: null, | ||
maxSize: 3 | ||
}); | ||
return new Uint8Array(bytes); | ||
}, | ||
fixedSize: null, | ||
maxSize: 3 | ||
}; | ||
}; | ||
var getU32Encoder = (config = {}) => numberEncoderFactory({ | ||
@@ -280,5 +306,6 @@ config, | ||
var getStringEncoder = (config = {}) => { | ||
const size = config.size ?? getU32Encoder(); | ||
const encoding = config.encoding ?? getUtf8Encoder(); | ||
const description = config.description ?? `string(${encoding.description}; ${getSizeDescription(size)})`; | ||
var _a, _b, _c; | ||
const size = (_a = config.size) != null ? _a : getU32Encoder(); | ||
const encoding = (_b = config.encoding) != null ? _b : getUtf8Encoder(); | ||
const description = (_c = config.description) != null ? _c : `string(${encoding.description}; ${getSizeDescription(size)})`; | ||
if (size === "variable") { | ||
@@ -302,5 +329,6 @@ return { ...encoding, description }; | ||
var getStringDecoder = (config = {}) => { | ||
const size = config.size ?? getU32Decoder(); | ||
const encoding = config.encoding ?? getUtf8Decoder(); | ||
const description = config.description ?? `string(${encoding.description}; ${getSizeDescription(size)})`; | ||
var _a, _b, _c; | ||
const size = (_a = config.size) != null ? _a : getU32Decoder(); | ||
const encoding = (_b = config.encoding) != null ? _b : getUtf8Decoder(); | ||
const description = (_c = config.description) != null ? _c : `string(${encoding.description}; ${getSizeDescription(size)})`; | ||
if (size === "variable") { | ||
@@ -364,4 +392,5 @@ return { ...encoding, description }; | ||
async function assertKeyGenerationIsAvailable() { | ||
var _a; | ||
assertIsSecureContext(); | ||
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.subtle?.generateKey !== "function") { | ||
if (typeof globalThis.crypto === "undefined" || typeof ((_a = globalThis.crypto.subtle) == null ? void 0 : _a.generateKey) !== "function") { | ||
throw new Error("No key generation implementation could be found"); | ||
@@ -376,4 +405,5 @@ } | ||
async function assertKeyExporterIsAvailable() { | ||
var _a; | ||
assertIsSecureContext(); | ||
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.subtle?.exportKey !== "function") { | ||
if (typeof globalThis.crypto === "undefined" || typeof ((_a = globalThis.crypto.subtle) == null ? void 0 : _a.exportKey) !== "function") { | ||
throw new Error("No key export implementation could be found"); | ||
@@ -383,4 +413,5 @@ } | ||
async function assertSigningCapabilityIsAvailable() { | ||
var _a; | ||
assertIsSecureContext(); | ||
if (typeof globalThis.crypto === "undefined" || typeof globalThis.crypto.subtle?.sign !== "function") { | ||
if (typeof globalThis.crypto === "undefined" || typeof ((_a = globalThis.crypto.subtle) == null ? void 0 : _a.sign) !== "function") { | ||
throw new Error("No signing implementation could be found"); | ||
@@ -445,5 +476,6 @@ } | ||
function getAddressEncoder(config) { | ||
var _a; | ||
return mapEncoder( | ||
getStringEncoder({ | ||
description: config?.description ?? "Address", | ||
description: (_a = config == null ? void 0 : config.description) != null ? _a : "Address", | ||
encoding: getMemoizedBase58Encoder(), | ||
@@ -456,4 +488,5 @@ size: 32 | ||
function getAddressDecoder(config) { | ||
var _a; | ||
return getStringDecoder({ | ||
description: config?.description ?? "Address", | ||
description: (_a = config == null ? void 0 : config.description) != null ? _a : "Address", | ||
encoding: getMemoizedBase58Decoder(), | ||
@@ -532,3 +565,3 @@ size: 32 | ||
return { | ||
description: description ?? `array(${item.description}; ${getArrayLikeCodecSizeDescription(size)})`, | ||
description: description != null ? description : `array(${item.description}; ${getArrayLikeCodecSizeDescription(size)})`, | ||
fixedSize: getArrayLikeCodecSizeFromChildren(size, [item.fixedSize]), | ||
@@ -539,3 +572,4 @@ maxSize: getArrayLikeCodecSizeFromChildren(size, [item.maxSize]) | ||
function getArrayEncoder(item, config = {}) { | ||
const size = config.size ?? getU32Encoder(); | ||
var _a; | ||
const size = (_a = config.size) != null ? _a : getU32Encoder(); | ||
return { | ||
@@ -552,5 +586,6 @@ ...arrayCodecHelper(item, size, config.description), | ||
function getBytesEncoder(config = {}) { | ||
const size = config.size ?? "variable"; | ||
var _a, _b; | ||
const size = (_a = config.size) != null ? _a : "variable"; | ||
const sizeDescription = typeof size === "object" ? size.description : `${size}`; | ||
const description = config.description ?? `bytes(${sizeDescription})`; | ||
const description = (_b = config.description) != null ? _b : `bytes(${sizeDescription})`; | ||
const byteEncoder = { | ||
@@ -580,3 +615,3 @@ description, | ||
return { | ||
description: description ?? `struct(${fieldDescriptions})`, | ||
description: description != null ? description : `struct(${fieldDescriptions})`, | ||
fixedSize: sumCodecSizes(fields.map(([, field]) => field.fixedSize)), | ||
@@ -617,3 +652,4 @@ maxSize: sumCodecSizes(fields.map(([, field]) => field.maxSize)) | ||
function upsert(addressMap, address2, update) { | ||
addressMap[address2] = update(addressMap[address2] ?? { role: AccountRole.READONLY }); | ||
var _a; | ||
addressMap[address2] = update((_a = addressMap[address2]) != null ? _a : { role: AccountRole.READONLY }); | ||
} | ||
@@ -915,3 +951,3 @@ var TYPE = Symbol("AddressMapTypeProperty"); | ||
...encoder, | ||
description: description ?? encoder.description | ||
description: description != null ? description : encoder.description | ||
}; | ||
@@ -956,2 +992,3 @@ } | ||
(instruction) => { | ||
var _a, _b; | ||
if (instruction.accountIndices !== void 0 && instruction.data !== void 0) { | ||
@@ -962,4 +999,4 @@ return instruction; | ||
...instruction, | ||
accountIndices: instruction.accountIndices ?? [], | ||
data: instruction.data ?? new Uint8Array(0) | ||
accountIndices: (_a = instruction.accountIndices) != null ? _a : [], | ||
data: (_b = instruction.data) != null ? _b : new Uint8Array(0) | ||
}; | ||
@@ -1006,2 +1043,3 @@ } | ||
(value) => { | ||
var _a; | ||
if (value.version === "legacy") { | ||
@@ -1012,3 +1050,3 @@ return value; | ||
...value, | ||
addressTableLookups: value.addressTableLookups ?? [] | ||
addressTableLookups: (_a = value.addressTableLookups) != null ? _a : [] | ||
}; | ||
@@ -1086,2 +1124,14 @@ } | ||
} | ||
function assertTransactionIsFullySigned(transaction) { | ||
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => { | ||
var _a, _b; | ||
return (_b = (_a = i.accounts) == null ? void 0 : _a.filter((a) => isSignerRole(a.role))) != null ? _b : []; | ||
}).map((a) => a.address); | ||
const requiredSigners = /* @__PURE__ */ new Set([transaction.feePayer, ...signerAddressesFromInstructions]); | ||
requiredSigners.forEach((address2) => { | ||
if (!transaction.signatures[address2]) { | ||
throw new Error(`Transaction is missing signature for address \`${address2}\``); | ||
} | ||
}); | ||
} | ||
@@ -1159,10 +1209,11 @@ // src/message-partial-signer.ts | ||
} | ||
var o2 = globalThis.TextEncoder; | ||
// src/signable-message.ts | ||
function createSignableMessage(content, signatures = {}) { | ||
return Object.freeze({ | ||
content: typeof content === "string" ? new o2().encode(content) : content, | ||
signatures: Object.freeze({ ...signatures }) | ||
}); | ||
// src/noop-signer.ts | ||
function createNoopSigner(address2) { | ||
const out = { | ||
address: address2, | ||
signMessages: async (messages) => messages.map(() => Object.freeze({})), | ||
signTransactions: async (transactions) => transactions.map(() => Object.freeze({})) | ||
}; | ||
return Object.freeze(out); | ||
} | ||
@@ -1200,2 +1251,108 @@ | ||
// src/sign-transaction.ts | ||
async function partiallySignTransactionWithSigners(transaction, config = {}) { | ||
var _a; | ||
const signers = (_a = config.signers) != null ? _a : []; | ||
const { partialSigners, modifyingSigners } = categorizeTransactionSigners( | ||
deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]), | ||
{ identifySendingSigner: false } | ||
); | ||
return signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config.abortSignal); | ||
} | ||
async function signTransactionWithSigners(transaction, config = {}) { | ||
const signedTransaction = await partiallySignTransactionWithSigners(transaction, config); | ||
assertTransactionIsFullySigned(signedTransaction); | ||
return signedTransaction; | ||
} | ||
async function signAndSendTransactionWithSigners(transaction, config = {}) { | ||
var _a; | ||
const signers = (_a = config.signers) != null ? _a : []; | ||
const abortSignal = config.abortSignal; | ||
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( | ||
deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]) | ||
); | ||
abortSignal == null ? void 0 : abortSignal.throwIfAborted(); | ||
const signedTransaction = await signModifyingAndPartialTransactionSigners( | ||
transaction, | ||
modifyingSigners, | ||
partialSigners, | ||
abortSignal | ||
); | ||
if (sendingSigner) { | ||
abortSignal == null ? void 0 : abortSignal.throwIfAborted(); | ||
const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); | ||
return signature; | ||
} | ||
if (config.fallbackSender) { | ||
assertTransactionIsFullySigned(signedTransaction); | ||
return config.fallbackSender(signedTransaction); | ||
} | ||
throw new Error("No TransactionSendingSigner was identified and no fallback sender was provided."); | ||
} | ||
function categorizeTransactionSigners(signers, config = {}) { | ||
var _a; | ||
const identifySendingSigner = (_a = config.identifySendingSigner) != null ? _a : true; | ||
const sendingSigner = identifySendingSigner ? identifyTransactionSendingSigner(signers) : null; | ||
const otherSigners = signers.filter( | ||
(signer) => signer !== sendingSigner && (isTransactionModifyingSigner(signer) || isTransactionPartialSigner(signer)) | ||
); | ||
const modifyingSigners = identifyTransactionModifyingSigners(otherSigners); | ||
const partialSigners = otherSigners.filter(isTransactionPartialSigner).filter((signer) => !modifyingSigners.includes(signer)); | ||
return Object.freeze({ modifyingSigners, partialSigners, sendingSigner }); | ||
} | ||
function identifyTransactionSendingSigner(signers) { | ||
const sendingSigners = signers.filter(isTransactionSendingSigner); | ||
if (sendingSigners.length === 0) | ||
return null; | ||
const sendingOnlySigners = sendingSigners.filter( | ||
(signer) => !isTransactionModifyingSigner(signer) && !isTransactionPartialSigner(signer) | ||
); | ||
if (sendingOnlySigners.length > 0) { | ||
return sendingOnlySigners[0]; | ||
} | ||
return sendingSigners[0]; | ||
} | ||
function identifyTransactionModifyingSigners(signers) { | ||
const modifyingSigners = signers.filter(isTransactionModifyingSigner); | ||
if (modifyingSigners.length === 0) | ||
return []; | ||
const nonPartialSigners = modifyingSigners.filter((signer) => !isTransactionPartialSigner(signer)); | ||
if (nonPartialSigners.length > 0) | ||
return nonPartialSigners; | ||
return [modifyingSigners[0]]; | ||
} | ||
async function signModifyingAndPartialTransactionSigners(transaction, modifyingSigners = [], partialSigners = [], abortSignal) { | ||
var _a; | ||
const modifiedTransaction = await modifyingSigners.reduce(async (transaction2, modifyingSigner) => { | ||
abortSignal == null ? void 0 : abortSignal.throwIfAborted(); | ||
const [tx] = await modifyingSigner.modifyAndSignTransactions([await transaction2], { abortSignal }); | ||
return Object.freeze(tx); | ||
}, Promise.resolve(transaction)); | ||
abortSignal == null ? void 0 : abortSignal.throwIfAborted(); | ||
const signatureDictionaries = await Promise.all( | ||
partialSigners.map(async (partialSigner) => { | ||
const [signatures] = await partialSigner.signTransactions([modifiedTransaction], { abortSignal }); | ||
return signatures; | ||
}) | ||
); | ||
const signedTransaction = { | ||
...modifiedTransaction, | ||
signatures: Object.freeze( | ||
signatureDictionaries.reduce((signatures, signatureDictionary) => { | ||
return { ...signatures, ...signatureDictionary }; | ||
}, (_a = modifiedTransaction.signatures) != null ? _a : {}) | ||
) | ||
}; | ||
return Object.freeze(signedTransaction); | ||
} | ||
var o2 = globalThis.TextEncoder; | ||
// src/signable-message.ts | ||
function createSignableMessage(content, signatures = {}) { | ||
return Object.freeze({ | ||
content: typeof content === "string" ? new o2().encode(content) : content, | ||
signatures: Object.freeze({ ...signatures }) | ||
}); | ||
} | ||
exports.assertIsKeyPairSigner = assertIsKeyPairSigner; | ||
@@ -1209,5 +1366,8 @@ exports.assertIsMessageModifyingSigner = assertIsMessageModifyingSigner; | ||
exports.assertIsTransactionSigner = assertIsTransactionSigner; | ||
exports.createNoopSigner = createNoopSigner; | ||
exports.createSignableMessage = createSignableMessage; | ||
exports.createSignerFromKeyPair = createSignerFromKeyPair; | ||
exports.generateKeyPairSigner = generateKeyPairSigner; | ||
exports.getSignersFromInstruction = getSignersFromInstruction; | ||
exports.getSignersFromTransaction = getSignersFromTransaction; | ||
exports.isKeyPairSigner = isKeyPairSigner; | ||
@@ -1221,2 +1381,5 @@ exports.isMessageModifyingSigner = isMessageModifyingSigner; | ||
exports.isTransactionSigner = isTransactionSigner; | ||
exports.partiallySignTransactionWithSigners = partiallySignTransactionWithSigners; | ||
exports.signAndSendTransactionWithSigners = signAndSendTransactionWithSigners; | ||
exports.signTransactionWithSigners = signTransactionWithSigners; | ||
@@ -1223,0 +1386,0 @@ return exports; |
import { getAddressFromPublicKey, isAddress } from '@solana/addresses'; | ||
import { generateKeyPair, signBytes } from '@solana/keys'; | ||
import { partiallySignTransaction } from '@solana/transactions'; | ||
import { assertTransactionIsFullySigned, partiallySignTransaction } from '@solana/transactions'; | ||
// src/keypair-signer.ts | ||
// src/deduplicate-signers.ts | ||
function deduplicateSigners(signers) { | ||
const deduplicated = {}; | ||
signers.forEach((signer) => { | ||
if (!deduplicated[signer.address]) { | ||
deduplicated[signer.address] = signer; | ||
} | ||
}); | ||
return Object.values(deduplicated); | ||
} | ||
// src/account-signer-meta.ts | ||
function getSignersFromInstruction(instruction) { | ||
return deduplicateSigners( | ||
(instruction.accounts ?? []).flatMap((account) => "signer" in account ? account.signer : []) | ||
); | ||
} | ||
function getSignersFromTransaction(transaction) { | ||
return deduplicateSigners(transaction.instructions.flatMap(getSignersFromInstruction)); | ||
} | ||
// src/message-partial-signer.ts | ||
@@ -76,10 +95,11 @@ function isMessagePartialSigner(value) { | ||
} | ||
var o = globalThis.TextEncoder; | ||
// src/signable-message.ts | ||
function createSignableMessage(content, signatures = {}) { | ||
return Object.freeze({ | ||
content: typeof content === "string" ? new o().encode(content) : content, | ||
signatures: Object.freeze({ ...signatures }) | ||
}); | ||
// src/noop-signer.ts | ||
function createNoopSigner(address) { | ||
const out = { | ||
address, | ||
signMessages: async (messages) => messages.map(() => Object.freeze({})), | ||
signTransactions: async (transactions) => transactions.map(() => Object.freeze({})) | ||
}; | ||
return Object.freeze(out); | ||
} | ||
@@ -117,4 +137,106 @@ | ||
export { assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner }; | ||
// src/sign-transaction.ts | ||
async function partiallySignTransactionWithSigners(transaction, config = {}) { | ||
const signers = config.signers ?? []; | ||
const { partialSigners, modifyingSigners } = categorizeTransactionSigners( | ||
deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]), | ||
{ identifySendingSigner: false } | ||
); | ||
return signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config.abortSignal); | ||
} | ||
async function signTransactionWithSigners(transaction, config = {}) { | ||
const signedTransaction = await partiallySignTransactionWithSigners(transaction, config); | ||
assertTransactionIsFullySigned(signedTransaction); | ||
return signedTransaction; | ||
} | ||
async function signAndSendTransactionWithSigners(transaction, config = {}) { | ||
const signers = config.signers ?? []; | ||
const abortSignal = config.abortSignal; | ||
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( | ||
deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]) | ||
); | ||
abortSignal?.throwIfAborted(); | ||
const signedTransaction = await signModifyingAndPartialTransactionSigners( | ||
transaction, | ||
modifyingSigners, | ||
partialSigners, | ||
abortSignal | ||
); | ||
if (sendingSigner) { | ||
abortSignal?.throwIfAborted(); | ||
const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); | ||
return signature; | ||
} | ||
if (config.fallbackSender) { | ||
assertTransactionIsFullySigned(signedTransaction); | ||
return config.fallbackSender(signedTransaction); | ||
} | ||
throw new Error("No TransactionSendingSigner was identified and no fallback sender was provided."); | ||
} | ||
function categorizeTransactionSigners(signers, config = {}) { | ||
const identifySendingSigner = config.identifySendingSigner ?? true; | ||
const sendingSigner = identifySendingSigner ? identifyTransactionSendingSigner(signers) : null; | ||
const otherSigners = signers.filter( | ||
(signer) => signer !== sendingSigner && (isTransactionModifyingSigner(signer) || isTransactionPartialSigner(signer)) | ||
); | ||
const modifyingSigners = identifyTransactionModifyingSigners(otherSigners); | ||
const partialSigners = otherSigners.filter(isTransactionPartialSigner).filter((signer) => !modifyingSigners.includes(signer)); | ||
return Object.freeze({ modifyingSigners, partialSigners, sendingSigner }); | ||
} | ||
function identifyTransactionSendingSigner(signers) { | ||
const sendingSigners = signers.filter(isTransactionSendingSigner); | ||
if (sendingSigners.length === 0) | ||
return null; | ||
const sendingOnlySigners = sendingSigners.filter( | ||
(signer) => !isTransactionModifyingSigner(signer) && !isTransactionPartialSigner(signer) | ||
); | ||
if (sendingOnlySigners.length > 0) { | ||
return sendingOnlySigners[0]; | ||
} | ||
return sendingSigners[0]; | ||
} | ||
function identifyTransactionModifyingSigners(signers) { | ||
const modifyingSigners = signers.filter(isTransactionModifyingSigner); | ||
if (modifyingSigners.length === 0) | ||
return []; | ||
const nonPartialSigners = modifyingSigners.filter((signer) => !isTransactionPartialSigner(signer)); | ||
if (nonPartialSigners.length > 0) | ||
return nonPartialSigners; | ||
return [modifyingSigners[0]]; | ||
} | ||
async function signModifyingAndPartialTransactionSigners(transaction, modifyingSigners = [], partialSigners = [], abortSignal) { | ||
const modifiedTransaction = await modifyingSigners.reduce(async (transaction2, modifyingSigner) => { | ||
abortSignal?.throwIfAborted(); | ||
const [tx] = await modifyingSigner.modifyAndSignTransactions([await transaction2], { abortSignal }); | ||
return Object.freeze(tx); | ||
}, Promise.resolve(transaction)); | ||
abortSignal?.throwIfAborted(); | ||
const signatureDictionaries = await Promise.all( | ||
partialSigners.map(async (partialSigner) => { | ||
const [signatures] = await partialSigner.signTransactions([modifiedTransaction], { abortSignal }); | ||
return signatures; | ||
}) | ||
); | ||
const signedTransaction = { | ||
...modifiedTransaction, | ||
signatures: Object.freeze( | ||
signatureDictionaries.reduce((signatures, signatureDictionary) => { | ||
return { ...signatures, ...signatureDictionary }; | ||
}, modifiedTransaction.signatures ?? {}) | ||
) | ||
}; | ||
return Object.freeze(signedTransaction); | ||
} | ||
var o = globalThis.TextEncoder; | ||
// src/signable-message.ts | ||
function createSignableMessage(content, signatures = {}) { | ||
return Object.freeze({ | ||
content: typeof content === "string" ? new o().encode(content) : content, | ||
signatures: Object.freeze({ ...signatures }) | ||
}); | ||
} | ||
export { assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createNoopSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, getSignersFromInstruction, getSignersFromTransaction, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner, partiallySignTransactionWithSigners, signAndSendTransactionWithSigners, signTransactionWithSigners }; | ||
//# sourceMappingURL=out.js.map | ||
//# sourceMappingURL=index.native.js.map |
import { getAddressFromPublicKey, isAddress } from '@solana/addresses'; | ||
import { generateKeyPair, signBytes } from '@solana/keys'; | ||
import { partiallySignTransaction } from '@solana/transactions'; | ||
import { assertTransactionIsFullySigned, partiallySignTransaction } from '@solana/transactions'; | ||
// src/keypair-signer.ts | ||
// src/deduplicate-signers.ts | ||
function deduplicateSigners(signers) { | ||
const deduplicated = {}; | ||
signers.forEach((signer) => { | ||
if (!deduplicated[signer.address]) { | ||
deduplicated[signer.address] = signer; | ||
} | ||
}); | ||
return Object.values(deduplicated); | ||
} | ||
// src/account-signer-meta.ts | ||
function getSignersFromInstruction(instruction) { | ||
return deduplicateSigners( | ||
(instruction.accounts ?? []).flatMap((account) => "signer" in account ? account.signer : []) | ||
); | ||
} | ||
function getSignersFromTransaction(transaction) { | ||
return deduplicateSigners(transaction.instructions.flatMap(getSignersFromInstruction)); | ||
} | ||
// src/message-partial-signer.ts | ||
@@ -76,10 +95,11 @@ function isMessagePartialSigner(value) { | ||
} | ||
var o = globalThis.TextEncoder; | ||
// src/signable-message.ts | ||
function createSignableMessage(content, signatures = {}) { | ||
return Object.freeze({ | ||
content: typeof content === "string" ? new o().encode(content) : content, | ||
signatures: Object.freeze({ ...signatures }) | ||
}); | ||
// src/noop-signer.ts | ||
function createNoopSigner(address) { | ||
const out = { | ||
address, | ||
signMessages: async (messages) => messages.map(() => Object.freeze({})), | ||
signTransactions: async (transactions) => transactions.map(() => Object.freeze({})) | ||
}; | ||
return Object.freeze(out); | ||
} | ||
@@ -117,4 +137,106 @@ | ||
export { assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner }; | ||
// src/sign-transaction.ts | ||
async function partiallySignTransactionWithSigners(transaction, config = {}) { | ||
const signers = config.signers ?? []; | ||
const { partialSigners, modifyingSigners } = categorizeTransactionSigners( | ||
deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]), | ||
{ identifySendingSigner: false } | ||
); | ||
return signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config.abortSignal); | ||
} | ||
async function signTransactionWithSigners(transaction, config = {}) { | ||
const signedTransaction = await partiallySignTransactionWithSigners(transaction, config); | ||
assertTransactionIsFullySigned(signedTransaction); | ||
return signedTransaction; | ||
} | ||
async function signAndSendTransactionWithSigners(transaction, config = {}) { | ||
const signers = config.signers ?? []; | ||
const abortSignal = config.abortSignal; | ||
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( | ||
deduplicateSigners([...getSignersFromTransaction(transaction).filter(isTransactionSigner), ...signers]) | ||
); | ||
abortSignal?.throwIfAborted(); | ||
const signedTransaction = await signModifyingAndPartialTransactionSigners( | ||
transaction, | ||
modifyingSigners, | ||
partialSigners, | ||
abortSignal | ||
); | ||
if (sendingSigner) { | ||
abortSignal?.throwIfAborted(); | ||
const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); | ||
return signature; | ||
} | ||
if (config.fallbackSender) { | ||
assertTransactionIsFullySigned(signedTransaction); | ||
return config.fallbackSender(signedTransaction); | ||
} | ||
throw new Error("No TransactionSendingSigner was identified and no fallback sender was provided."); | ||
} | ||
function categorizeTransactionSigners(signers, config = {}) { | ||
const identifySendingSigner = config.identifySendingSigner ?? true; | ||
const sendingSigner = identifySendingSigner ? identifyTransactionSendingSigner(signers) : null; | ||
const otherSigners = signers.filter( | ||
(signer) => signer !== sendingSigner && (isTransactionModifyingSigner(signer) || isTransactionPartialSigner(signer)) | ||
); | ||
const modifyingSigners = identifyTransactionModifyingSigners(otherSigners); | ||
const partialSigners = otherSigners.filter(isTransactionPartialSigner).filter((signer) => !modifyingSigners.includes(signer)); | ||
return Object.freeze({ modifyingSigners, partialSigners, sendingSigner }); | ||
} | ||
function identifyTransactionSendingSigner(signers) { | ||
const sendingSigners = signers.filter(isTransactionSendingSigner); | ||
if (sendingSigners.length === 0) | ||
return null; | ||
const sendingOnlySigners = sendingSigners.filter( | ||
(signer) => !isTransactionModifyingSigner(signer) && !isTransactionPartialSigner(signer) | ||
); | ||
if (sendingOnlySigners.length > 0) { | ||
return sendingOnlySigners[0]; | ||
} | ||
return sendingSigners[0]; | ||
} | ||
function identifyTransactionModifyingSigners(signers) { | ||
const modifyingSigners = signers.filter(isTransactionModifyingSigner); | ||
if (modifyingSigners.length === 0) | ||
return []; | ||
const nonPartialSigners = modifyingSigners.filter((signer) => !isTransactionPartialSigner(signer)); | ||
if (nonPartialSigners.length > 0) | ||
return nonPartialSigners; | ||
return [modifyingSigners[0]]; | ||
} | ||
async function signModifyingAndPartialTransactionSigners(transaction, modifyingSigners = [], partialSigners = [], abortSignal) { | ||
const modifiedTransaction = await modifyingSigners.reduce(async (transaction2, modifyingSigner) => { | ||
abortSignal?.throwIfAborted(); | ||
const [tx] = await modifyingSigner.modifyAndSignTransactions([await transaction2], { abortSignal }); | ||
return Object.freeze(tx); | ||
}, Promise.resolve(transaction)); | ||
abortSignal?.throwIfAborted(); | ||
const signatureDictionaries = await Promise.all( | ||
partialSigners.map(async (partialSigner) => { | ||
const [signatures] = await partialSigner.signTransactions([modifiedTransaction], { abortSignal }); | ||
return signatures; | ||
}) | ||
); | ||
const signedTransaction = { | ||
...modifiedTransaction, | ||
signatures: Object.freeze( | ||
signatureDictionaries.reduce((signatures, signatureDictionary) => { | ||
return { ...signatures, ...signatureDictionary }; | ||
}, modifiedTransaction.signatures ?? {}) | ||
) | ||
}; | ||
return Object.freeze(signedTransaction); | ||
} | ||
var o = globalThis.TextEncoder; | ||
// src/signable-message.ts | ||
function createSignableMessage(content, signatures = {}) { | ||
return Object.freeze({ | ||
content: typeof content === "string" ? new o().encode(content) : content, | ||
signatures: Object.freeze({ ...signatures }) | ||
}); | ||
} | ||
export { assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createNoopSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, getSignersFromInstruction, getSignersFromTransaction, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner, partiallySignTransactionWithSigners, signAndSendTransactionWithSigners, signTransactionWithSigners }; | ||
//# sourceMappingURL=out.js.map | ||
//# sourceMappingURL=index.node.js.map |
@@ -5,27 +5,33 @@ this.globalThis = this.globalThis || {}; | ||
function w(e,n,r=0){if(n.length-r<=0)throw new Error(`Codec [${e}] cannot decode empty byte arrays.`)}function x(e,n,r,t=0){let i=r.length-t;if(i<n)throw new Error(`Codec [${e}] expected ${n} bytes, got ${i}.`)}var b=e=>{let n=e.filter(o=>o.length);if(n.length===0)return e.length?e[0]:new Uint8Array;if(n.length===1)return n[0];let r=n.reduce((o,s)=>o+s.length,0),t=new Uint8Array(r),i=0;return n.forEach(o=>{t.set(o,i),i+=o.length;}),t},Ae=(e,n)=>{if(e.length>=n)return e;let r=new Uint8Array(n).fill(0);return r.set(e),r},R=(e,n)=>Ae(e.length<=n?e:e.slice(0,n),n);function ne(e,n,r){return {description:r??`fixed(${n}, ${e.description})`,fixedSize:n,maxSize:n}}function C(e,n,r){return {...ne(e,n,r),encode:t=>R(e.encode(t),n)}}function O(e,n,r){return {...ne(e,n,r),decode:(t,i=0)=>{x("fixCodec",n,t,i),(i>0||t.length>n)&&(t=t.slice(i,i+n)),e.fixedSize!==null&&(t=R(t,e.fixedSize));let[o]=e.decode(t,0);return [o,i+n]}}}function T(e,n){return {description:e.description,encode:r=>e.encode(n(r)),fixedSize:e.fixedSize,maxSize:e.maxSize}}function re(e,n,r,t){if(t<n||t>r)throw new Error(`Codec [${e}] expected number to be in the range [${n}, ${r}], got ${t}.`)}function te(e){let n,r=e.name;return e.size>1&&(n=!("endian"in e.config)||e.config.endian===0,r+=n?"(le)":"(be)"),{description:e.config.description??r,fixedSize:e.size,littleEndian:n,maxSize:e.size}}function ie(e){let n=te(e);return {description:n.description,encode(r){e.range&&re(e.name,e.range[0],e.range[1],r);let t=new ArrayBuffer(e.size);return e.set(new DataView(t),r,n.littleEndian),new Uint8Array(t)},fixedSize:n.fixedSize,maxSize:n.maxSize}}function we(e){let n=te(e);return {decode(r,t=0){w(n.description,r,t),x(n.description,e.size,r,t);let i=new DataView(Te(r,t,e.size));return [e.get(i,n.littleEndian),t+e.size]},description:n.description,fixedSize:n.fixedSize,maxSize:n.maxSize}}function Te(e,n,r){let t=e.byteOffset+(n??0),i=r??e.byteLength;return e.buffer.slice(t,t+i)}var m=(e={})=>({description:e.description??"shortU16",encode:n=>{re("shortU16",0,65535,n);let r=[0];for(let t=0;;t+=1){let i=n>>t*7;if(i===0)break;let o=127&i;r[t]=o,t>0&&(r[t-1]|=128);}return new Uint8Array(r)},fixedSize:null,maxSize:3});var k=(e={})=>ie({config:e,name:"u32",range:[0,+"0xffffffff"],set:(n,r,t)=>n.setUint32(0,r,t),size:4}),L=(e={})=>we({config:e,get:(n,r)=>n.getUint32(0,r),name:"u32",size:4});var h=(e={})=>ie({config:e,name:"u8",range:[0,+"0xff"],set:(n,r)=>n.setUint8(0,r),size:1});function ze(e,n,r=n){if(!n.match(new RegExp(`^[${e}]*$`)))throw new Error(`Expected a string of base ${e.length}, got [${r}].`)}var Ee=e=>{let n=e.length,r=BigInt(n);return {description:`base${n}`,encode(t){if(ze(e,t),t==="")return new Uint8Array;let i=[...t],o=i.findIndex(p=>p!==e[0]);o=o===-1?i.length:o;let s=Array(o).fill(0);if(o===i.length)return Uint8Array.from(s);let a=i.slice(o),l=0n,d=1n;for(let p=a.length-1;p>=0;p-=1)l+=d*BigInt(e.indexOf(a[p])),d*=r;let u=[];for(;l>0n;)u.unshift(Number(l%256n)),l/=256n;return Uint8Array.from(s.concat(u))},fixedSize:null,maxSize:null}},ve=e=>{let n=e.length,r=BigInt(n);return {decode(t,i=0){let o=i===0?t:t.slice(i);if(o.length===0)return ["",0];let s=o.findIndex(u=>u!==0);s=s===-1?o.length:s;let a=e[0].repeat(s);if(s===o.length)return [a,t.length];let l=o.slice(s).reduce((u,p)=>u*256n+BigInt(p),0n),d=[];for(;l>0n;)d.unshift(e[Number(l%r)]),l/=r;return [a+d.join(""),t.length]},description:`base${n}`,fixedSize:null,maxSize:null}};var oe="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",M=()=>Ee(oe),_=()=>ve(oe);var Ie=e=>e.replace(/\u0000/g,"");var De=globalThis.TextDecoder,Ce=globalThis.TextEncoder,Be=()=>{let e;return {description:"utf8",encode:n=>new Uint8Array((e||(e=new Ce)).encode(n)),fixedSize:null,maxSize:null}},ke=()=>{let e;return {decode(n,r=0){let t=(e||(e=new De)).decode(n.slice(r));return [Ie(t),n.length]},description:"utf8",fixedSize:null,maxSize:null}};var $=(e={})=>{let n=e.size??k(),r=e.encoding??Be(),t=e.description??`string(${r.description}; ${se(n)})`;return n==="variable"?{...r,description:t}:typeof n=="number"?C(r,n,t):{description:t,encode:i=>{let o=r.encode(i),s=n.encode(o.length);return b([s,o])},fixedSize:null,maxSize:null}},F=(e={})=>{let n=e.size??L(),r=e.encoding??ke(),t=e.description??`string(${r.description}; ${se(n)})`;return n==="variable"?{...r,description:t}:typeof n=="number"?O(r,n,t):{decode:(i,o=0)=>{w("string",i,o);let[s,a]=n.decode(i,o),l=Number(s);o=a;let d=i.slice(o,o+l);x("string",l,d);let[u,p]=r.decode(d);return o+=p,[u,o]},description:t,fixedSize:null,maxSize:null}};function se(e){return typeof e=="object"?e.description:`${e}`}function K(){if(!globalThis.isSecureContext)throw new Error("Cryptographic operations are only allowed in secure browser contexts. Read more here: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts")}var S;async function Me(e){return S===void 0&&(S=new Promise(n=>{e.generateKey("Ed25519",!1,["sign","verify"]).catch(()=>{n(S=!1);}).then(()=>{n(S=!0);});})),typeof S=="boolean"?S:await S}async function ae(){if(K(),typeof globalThis.crypto>"u"||typeof globalThis.crypto.subtle?.generateKey!="function")throw new Error("No key generation implementation could be found");if(!await Me(globalThis.crypto.subtle))throw new Error(`This runtime does not support the generation of Ed25519 key pairs. | ||
function A(e){let n={};return e.forEach(r=>{n[r.address]||(n[r.address]=r);}),Object.values(n)}function De(e){var n;return A(((n=e.accounts)!=null?n:[]).flatMap(r=>"signer"in r?r.signer:[]))}function _(e){return A(e.instructions.flatMap(De))}function I(e,n,r=0){if(n.length-r<=0)throw new Error(`Codec [${e}] cannot decode empty byte arrays.`)}function b(e,n,r,t=0){let i=r.length-t;if(i<n)throw new Error(`Codec [${e}] expected ${n} bytes, got ${i}.`)}var w=e=>{let n=e.filter(o=>o.length);if(n.length===0)return e.length?e[0]:new Uint8Array;if(n.length===1)return n[0];let r=n.reduce((o,s)=>o+s.length,0),t=new Uint8Array(r),i=0;return n.forEach(o=>{t.set(o,i),i+=o.length;}),t},Me=(e,n)=>{if(e.length>=n)return e;let r=new Uint8Array(n).fill(0);return r.set(e),r},W=(e,n)=>Me(e.length<=n?e:e.slice(0,n),n);function se(e,n,r){return {description:r!=null?r:`fixed(${n}, ${e.description})`,fixedSize:n,maxSize:n}}function k(e,n,r){return {...se(e,n,r),encode:t=>W(e.encode(t),n)}}function j(e,n,r){return {...se(e,n,r),decode:(t,i=0)=>{b("fixCodec",n,t,i),(i>0||t.length>n)&&(t=t.slice(i,i+n)),e.fixedSize!==null&&(t=W(t,e.fixedSize));let[o]=e.decode(t,0);return [o,i+n]}}}function v(e,n){return {description:e.description,encode:r=>e.encode(n(r)),fixedSize:e.fixedSize,maxSize:e.maxSize}}function ae(e,n,r,t){if(t<n||t>r)throw new Error(`Codec [${e}] expected number to be in the range [${n}, ${r}], got ${t}.`)}function ce(e){var t;let n,r=e.name;return e.size>1&&(n=!("endian"in e.config)||e.config.endian===0,r+=n?"(le)":"(be)"),{description:(t=e.config.description)!=null?t:r,fixedSize:e.size,littleEndian:n,maxSize:e.size}}function de(e){let n=ce(e);return {description:n.description,encode(r){e.range&&ae(e.name,e.range[0],e.range[1],r);let t=new ArrayBuffer(e.size);return e.set(new DataView(t),r,n.littleEndian),new Uint8Array(t)},fixedSize:n.fixedSize,maxSize:n.maxSize}}function ke(e){let n=ce(e);return {decode(r,t=0){I(n.description,r,t),b(n.description,e.size,r,t);let i=new DataView(Pe(r,t,e.size));return [e.get(i,n.littleEndian),t+e.size]},description:n.description,fixedSize:n.fixedSize,maxSize:n.maxSize}}function Pe(e,n,r){let t=e.byteOffset+(n!=null?n:0),i=r!=null?r:e.byteLength;return e.buffer.slice(t,t+i)}var S=(e={})=>{var n;return {description:(n=e.description)!=null?n:"shortU16",encode:r=>{ae("shortU16",0,65535,r);let t=[0];for(let i=0;;i+=1){let o=r>>i*7;if(o===0)break;let s=127&o;t[i]=s,i>0&&(t[i-1]|=128);}return new Uint8Array(t)},fixedSize:null,maxSize:3}};var $=(e={})=>de({config:e,name:"u32",range:[0,+"0xffffffff"],set:(n,r,t)=>n.setUint32(0,r,t),size:4}),K=(e={})=>ke({config:e,get:(n,r)=>n.getUint32(0,r),name:"u32",size:4});var y=(e={})=>de({config:e,name:"u8",range:[0,+"0xff"],set:(n,r)=>n.setUint8(0,r),size:1});function $e(e,n,r=n){if(!n.match(new RegExp(`^[${e}]*$`)))throw new Error(`Expected a string of base ${e.length}, got [${r}].`)}var Ue=e=>{let n=e.length,r=BigInt(n);return {description:`base${n}`,encode(t){if($e(e,t),t==="")return new Uint8Array;let i=[...t],o=i.findIndex(m=>m!==e[0]);o=o===-1?i.length:o;let s=Array(o).fill(0);if(o===i.length)return Uint8Array.from(s);let a=i.slice(o),c=0n,d=1n;for(let m=a.length-1;m>=0;m-=1)c+=d*BigInt(e.indexOf(a[m])),d*=r;let u=[];for(;c>0n;)u.unshift(Number(c%256n)),c/=256n;return Uint8Array.from(s.concat(u))},fixedSize:null,maxSize:null}},Ne=e=>{let n=e.length,r=BigInt(n);return {decode(t,i=0){let o=i===0?t:t.slice(i);if(o.length===0)return ["",0];let s=o.findIndex(u=>u!==0);s=s===-1?o.length:s;let a=e[0].repeat(s);if(s===o.length)return [a,t.length];let c=o.slice(s).reduce((u,m)=>u*256n+BigInt(m),0n),d=[];for(;c>0n;)d.unshift(e[Number(c%r)]),c/=r;return [a+d.join(""),t.length]},description:`base${n}`,fixedSize:null,maxSize:null}};var ue="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",U=()=>Ue(ue),V=()=>Ne(ue);var Oe=e=>e.replace(/\u0000/g,"");var Re=globalThis.TextDecoder,Le=globalThis.TextEncoder,Fe=()=>{let e;return {description:"utf8",encode:n=>new Uint8Array((e||(e=new Le)).encode(n)),fixedSize:null,maxSize:null}},_e=()=>{let e;return {decode(n,r=0){let t=(e||(e=new Re)).decode(n.slice(r));return [Oe(t),n.length]},description:"utf8",fixedSize:null,maxSize:null}};var N=(e={})=>{var i,o,s;let n=(i=e.size)!=null?i:$(),r=(o=e.encoding)!=null?o:Fe(),t=(s=e.description)!=null?s:`string(${r.description}; ${ge(n)})`;return n==="variable"?{...r,description:t}:typeof n=="number"?k(r,n,t):{description:t,encode:a=>{let c=r.encode(a),d=n.encode(c.length);return w([d,c])},fixedSize:null,maxSize:null}},H=(e={})=>{var i,o,s;let n=(i=e.size)!=null?i:K(),r=(o=e.encoding)!=null?o:_e(),t=(s=e.description)!=null?s:`string(${r.description}; ${ge(n)})`;return n==="variable"?{...r,description:t}:typeof n=="number"?j(r,n,t):{decode:(a,c=0)=>{I("string",a,c);let[d,u]=n.decode(a,c),m=Number(d);c=u;let oe=a.slice(c,c+m);b("string",m,oe);let[Ce,Be]=r.decode(oe);return c+=Be,[Ce,c]},description:t,fixedSize:null,maxSize:null}};function ge(e){return typeof e=="object"?e.description:`${e}`}function G(){if(!globalThis.isSecureContext)throw new Error("Cryptographic operations are only allowed in secure browser contexts. Read more here: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts")}var h;async function We(e){return h===void 0&&(h=new Promise(n=>{e.generateKey("Ed25519",!1,["sign","verify"]).catch(()=>{n(h=!1);}).then(()=>{n(h=!0);});})),typeof h=="boolean"?h:await h}async function fe(){var e;if(G(),typeof globalThis.crypto>"u"||typeof((e=globalThis.crypto.subtle)==null?void 0:e.generateKey)!="function")throw new Error("No key generation implementation could be found");if(!await We(globalThis.crypto.subtle))throw new Error(`This runtime does not support the generation of Ed25519 key pairs. | ||
Install and import \`@solana/webcrypto-ed25519-polyfill\` before generating keys in environments that do not support Ed25519. | ||
For a list of runtimes that currently support Ed25519 operations, visit https://github.com/WICG/webcrypto-secure-curves/issues/20`)}async function de(){if(K(),typeof globalThis.crypto>"u"||typeof globalThis.crypto.subtle?.exportKey!="function")throw new Error("No key export implementation could be found")}async function ce(){if(K(),typeof globalThis.crypto>"u"||typeof globalThis.crypto.subtle?.sign!="function")throw new Error("No signing implementation could be found")}var j,V;function H(){return j||(j=M()),j}function $e(){return V||(V=_()),V}function ue(e){return !(e.length<32||e.length>44||H().encode(e).byteLength!==32)}function fe(e){try{if(e.length<32||e.length>44)throw new Error("Expected input string to decode to a byte array of length 32.");let t=H().encode(e).byteLength;if(t!==32)throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${t}`)}catch(n){throw new Error(`\`${e}\` is not a base-58 encoded address`,{cause:n})}}function Ue(e){return fe(e),e}function W(e){return T($({description:e?.description??"Address",encoding:H(),size:32}),n=>Ue(n))}function le(e){return F({description:e?.description??"Address",encoding:$e(),size:32})}function U(){return new Intl.Collator("en",{caseFirst:"lower",ignorePunctuation:!1,localeMatcher:"best fit",numeric:!1,sensitivity:"variant",usage:"sort"}).compare}async function P(e){if(await de(),e.type!=="public"||e.algorithm.name!=="Ed25519")throw new Error("The `CryptoKey` must be an `Ed25519` public key");let n=await crypto.subtle.exportKey("raw",e),[r]=le().decode(new Uint8Array(n));return r}async function ge(){return await ae(),await crypto.subtle.generateKey("Ed25519",!1,["sign","verify"])}async function N(e,n){await ce();let r=await crypto.subtle.sign("Ed25519",e,n);return new Uint8Array(r)}function G(e){return e.reduce((n,r)=>n===null||r===null?null:n+r,0)}function Ne(e){return typeof e=="object"?e.description:`${e}`}function pe(e,n){if(typeof e!="number")return null;if(e===0)return 0;let r=G(n);return r===null?null:r*e}function Re(e,n){return typeof e=="object"?e.encode(n):new Uint8Array}function Oe(e,n,r){if(n!==r)throw new Error(`Expected [${e}] to have ${n} items, got ${r}.`)}function Le(e,n,r){if(n==="remainder"&&e.fixedSize===null)throw new Error('Codecs of "remainder" size must have fixed-size items.');return {description:r??`array(${e.description}; ${Ne(n)})`,fixedSize:pe(n,[e.fixedSize]),maxSize:pe(n,[e.maxSize])}}function y(e,n={}){let r=n.size??k();return {...Le(e,r,n.description),encode:t=>(typeof r=="number"&&Oe("array",r,t.length),b([Re(r,t.length),...t.map(i=>e.encode(i))]))}}function me(e={}){let n=e.size??"variable",r=typeof n=="object"?n.description:`${n}`,t=e.description??`bytes(${r})`,i={description:t,encode:o=>o,fixedSize:null,maxSize:null};return n==="variable"?i:typeof n=="number"?C(i,n,t):{...i,encode:o=>{let s=i.encode(o),a=n.encode(s.length);return b([a,s])}}}function _e(e,n){let r=e.map(([t,i])=>`${String(t)}: ${i.description}`).join(", ");return {description:n??`struct(${r})`,fixedSize:G(e.map(([,t])=>t.fixedSize)),maxSize:G(e.map(([,t])=>t.maxSize))}}function A(e,n={}){return {..._e(e,n.description),encode:r=>{let t=e.map(([i,o])=>o.encode(r[i]));return b(t)}}}var z=(e=>(e[e.WRITABLE_SIGNER=3]="WRITABLE_SIGNER",e[e.READONLY_SIGNER=2]="READONLY_SIGNER",e[e.WRITABLE=1]="WRITABLE",e[e.READONLY=0]="READONLY",e))(z||{}),Fe=1;function E(e){return e>=2}function v(e){return (e&Fe)!==0}function he(e,n){return e|n}function Se(e,n,r){e[n]=r(e[n]??{role:z.READONLY});}var c=Symbol("AddressMapTypeProperty");function Ke(e,n){let r={[e]:{[c]:0,role:z.WRITABLE_SIGNER}},t=new Set;for(let i of n){Se(r,i.programAddress,s=>{if(t.add(i.programAddress),c in s){if(v(s.role))switch(s[c]){case 0:throw new Error(`This transaction includes an address (\`${i.programAddress}\`) which is both invoked and set as the fee payer. Program addresses may not pay fees.`);default:throw new Error(`This transaction includes an address (\`${i.programAddress}\`) which is both invoked and marked writable. Program addresses may not be writable.`)}if(s[c]===2)return s}return {[c]:2,role:z.READONLY}});let o;if(i.accounts)for(let s of i.accounts)Se(r,s.address,a=>{let{address:l,...d}=s;if(c in a)switch(a[c]){case 0:return a;case 1:{let u=he(a.role,d.role);if("lookupTableAddress"in d){if(a.lookupTableAddress!==d.lookupTableAddress&&(o||(o=U()))(d.lookupTableAddress,a.lookupTableAddress)<0)return {[c]:1,...d,role:u}}else if(E(d.role))return {[c]:2,role:u};return a.role!==u?{...a,role:u}:a}case 2:{let u=he(a.role,d.role);if(t.has(s.address)){if(v(d.role))throw new Error(`This transaction includes an address (\`${s.address}\`) which is both invoked and marked writable. Program addresses may not be writable.`);return a.role!==u?{...a,role:u}:a}else return "lookupTableAddress"in d&&!E(a.role)?{...d,[c]:1,role:u}:a.role!==u?{...a,role:u}:a}}return "lookupTableAddress"in d?{...d,[c]:1}:{...d,[c]:2}});}return r}function je(e){let n;return Object.entries(e).sort(([t,i],[o,s])=>{if(i[c]!==s[c]){if(i[c]===0)return -1;if(s[c]===0)return 1;if(i[c]===2)return -1;if(s[c]===2)return 1}let a=E(i.role);if(a!==E(s.role))return a?-1:1;let l=v(i.role);return l!==v(s.role)?l?-1:1:(n||(n=U()),i[c]===1&&s[c]===1&&i.lookupTableAddress!==s.lookupTableAddress?n(i.lookupTableAddress,s.lookupTableAddress):n(t,o))}).map(([t,i])=>({address:t,...i}))}function Ve(e){var n;let r={};for(let t of e){if(!("lookupTableAddress"in t))continue;let i=r[n=t.lookupTableAddress]||(r[n]={readableIndices:[],writableIndices:[]});t.role===z.WRITABLE?i.writableIndices.push(t.addressIndex):i.readableIndices.push(t.addressIndex);}return Object.keys(r).sort(U()).map(t=>({lookupTableAddress:t,...r[t]}))}function He(e){let n=0,r=0,t=0;for(let i of e){if("lookupTableAddress"in i)break;let o=v(i.role);E(i.role)?(t++,o||r++):o||n++;}return {numReadonlyNonSignerAccounts:n,numReadonlySignerAccounts:r,numSignerAccounts:t}}function We(e){let n={};for(let[r,t]of e.entries())n[t.address]=r;return n}function Ge(e,n){let r=We(n);return e.map(({accounts:t,data:i,programAddress:o})=>({programAddressIndex:r[o],...t?{accountIndices:t.map(({address:s})=>r[s])}:null,...i?{data:i}:null}))}function Ye(e){return "nonce"in e?e.nonce:e.blockhash}function Xe(e){let n=e.findIndex(t=>"lookupTableAddress"in t);return (n===-1?e:e.slice(0,n)).map(({address:t})=>t)}function qe(e){let n=Ke(e.feePayer,e.instructions),r=je(n);return {...e.version!=="legacy"?{addressTableLookups:Ve(r)}:null,header:He(r),instructions:Ge(e.instructions,r),lifetimeToken:Ye(e.lifetimeConstraint),staticAccounts:Xe(r),version:e.version}}var Ze="lookupTableAddress",Je="writableIndices",Qe="readableIndices",en="addressTableLookup",Y;function nn(){return Y||(Y=A([["lookupTableAddress",W({description:Ze})],["writableIndices",y(h(),{description:Je,size:m()})],["readableIndices",y(h(),{description:Qe,size:m()})]],{description:en})),Y}var X;function rn(){return X||(X=h()),X}function q(e){let n=rn();return {...n,description:e??n.description}}var tn=void 0,on=void 0,sn=void 0,an=void 0;function dn(){return A([["numSignerAccounts",q(tn)],["numReadonlySignerAccounts",q(on)],["numReadonlyNonSignerAccounts",q(sn)]],{description:an})}var cn="programAddressIndex",un=void 0,fn="accountIndices",ln="data",Z;function gn(){return Z||(Z=T(A([["programAddressIndex",h({description:cn})],["accountIndices",y(h({description:un}),{description:fn,size:m()})],["data",me({description:ln,size:m()})]]),e=>e.accountIndices!==void 0&&e.data!==void 0?e:{...e,accountIndices:e.accountIndices??[],data:e.data??new Uint8Array(0)})),Z}var pn=128,mn={description:"",fixedSize:null,maxSize:1};function hn(e){if(e==="legacy")return new Uint8Array;if(e<0||e>127)throw new Error(`Transaction version must be in the range [0, 127]. \`${e}\` given.`);return new Uint8Array([e|pn])}function Sn(){return {...mn,encode:hn}}var yn="staticAccounts",xn="lifetimeToken",bn="instructions",An="addressTableLookups";function wn(){return A(ye())}function Tn(){return T(A([...ye(),["addressTableLookups",zn()]]),e=>e.version==="legacy"?e:{...e,addressTableLookups:e.addressTableLookups??[]})}function ye(){return [["version",Sn()],["header",dn()],["staticAccounts",y(W(),{description:yn,size:m()})],["lifetimeToken",$({description:xn,encoding:M(),size:32})],["instructions",y(gn(),{description:bn,size:m()})]]}function zn(){return y(nn(),{description:An,size:m()})}var En="message";function vn(){return {description:En,encode:e=>e.version==="legacy"?wn().encode(e):Tn().encode(e),fixedSize:null,maxSize:null}}async function xe(e,n){let r=qe(n),t="signatures"in n?{...n.signatures}:{},i=vn().encode(r),o=await Promise.all(e.map(a=>Promise.all([P(a.publicKey),N(a.privateKey,i)])));for(let[a,l]of o)t[a]=l;let s={...n,signatures:t};return Object.freeze(s),s}function I(e){return "signMessages"in e&&typeof e.signMessages=="function"}function yr(e){if(!I(e))throw new Error("The provided value does not implement the MessagePartialSigner interface")}function D(e){return "signTransactions"in e&&typeof e.signTransactions=="function"}function Ar(e){if(!D(e))throw new Error("The provided value does not implement the TransactionPartialSigner interface")}function In(e){return "keyPair"in e&&typeof e.keyPair=="object"&&I(e)&&D(e)}function Mr(e){if(!In(e))throw new Error("The provided value does not implement the KeyPairSigner interface")}async function Dn(e){let n=await P(e.publicKey);return Object.freeze({address:n,keyPair:e,signMessages:t=>Promise.all(t.map(async i=>Object.freeze({[n]:await N(e.privateKey,i.content)}))),signTransactions:t=>Promise.all(t.map(async i=>{let o=await xe([e],i);return Object.freeze({[n]:o.signatures[n]})}))})}async function $r(){return Dn(await ge())}function J(e){return ue(e.address)&&"modifyAndSignMessages"in e&&typeof e.modifyAndSignMessages=="function"}function Or(e){if(!J(e))throw new Error("The provided value does not implement the MessageModifyingSigner interface")}function Cn(e){return I(e)||J(e)}function Hr(e){if(!Cn(e))throw new Error("The provided value does not implement any of the MessageSigner interfaces")}var be=globalThis.TextEncoder;function Jr(e,n={}){return Object.freeze({content:typeof e=="string"?new be().encode(e):e,signatures:Object.freeze({...n})})}function Q(e){return "modifyAndSignTransactions"in e&&typeof e.modifyAndSignTransactions=="function"}function nt(e){if(!Q(e))throw new Error("The provided value does not implement the TransactionModifyingSigner interface")}function ee(e){return "signAndSendTransactions"in e&&typeof e.signAndSendTransactions=="function"}function it(e){if(!ee(e))throw new Error("The provided value does not implement the TransactionSendingSigner interface")}function Bn(e){return D(e)||Q(e)||ee(e)}function gt(e){if(!Bn(e))throw new Error("The provided value does not implement any of the TransactionSigner interfaces")} | ||
For a list of runtimes that currently support Ed25519 operations, visit https://github.com/WICG/webcrypto-secure-curves/issues/20`)}async function le(){var e;if(G(),typeof globalThis.crypto>"u"||typeof((e=globalThis.crypto.subtle)==null?void 0:e.exportKey)!="function")throw new Error("No key export implementation could be found")}async function me(){var e;if(G(),typeof globalThis.crypto>"u"||typeof((e=globalThis.crypto.subtle)==null?void 0:e.sign)!="function")throw new Error("No signing implementation could be found")}var Y,X;function q(){return Y||(Y=U()),Y}function je(){return X||(X=V()),X}function pe(e){return !(e.length<32||e.length>44||q().encode(e).byteLength!==32)}function Se(e){try{if(e.length<32||e.length>44)throw new Error("Expected input string to decode to a byte array of length 32.");let t=q().encode(e).byteLength;if(t!==32)throw new Error(`Expected input string to decode to a byte array of length 32. Actual length: ${t}`)}catch(n){throw new Error(`\`${e}\` is not a base-58 encoded address`,{cause:n})}}function Ke(e){return Se(e),e}function Z(e){var n;return v(N({description:(n=e==null?void 0:e.description)!=null?n:"Address",encoding:q(),size:32}),r=>Ke(r))}function ye(e){var n;return H({description:(n=e==null?void 0:e.description)!=null?n:"Address",encoding:je(),size:32})}function O(){return new Intl.Collator("en",{caseFirst:"lower",ignorePunctuation:!1,localeMatcher:"best fit",numeric:!1,sensitivity:"variant",usage:"sort"}).compare}async function R(e){if(await le(),e.type!=="public"||e.algorithm.name!=="Ed25519")throw new Error("The `CryptoKey` must be an `Ed25519` public key");let n=await crypto.subtle.exportKey("raw",e),[r]=ye().decode(new Uint8Array(n));return r}async function he(){return await fe(),await crypto.subtle.generateKey("Ed25519",!1,["sign","verify"])}async function L(e,n){await me();let r=await crypto.subtle.sign("Ed25519",e,n);return new Uint8Array(r)}function J(e){return e.reduce((n,r)=>n===null||r===null?null:n+r,0)}function He(e){return typeof e=="object"?e.description:`${e}`}function Te(e,n){if(typeof e!="number")return null;if(e===0)return 0;let r=J(n);return r===null?null:r*e}function Ge(e,n){return typeof e=="object"?e.encode(n):new Uint8Array}function Ye(e,n,r){if(n!==r)throw new Error(`Expected [${e}] to have ${n} items, got ${r}.`)}function Xe(e,n,r){if(n==="remainder"&&e.fixedSize===null)throw new Error('Codecs of "remainder" size must have fixed-size items.');return {description:r!=null?r:`array(${e.description}; ${He(n)})`,fixedSize:Te(n,[e.fixedSize]),maxSize:Te(n,[e.maxSize])}}function T(e,n={}){var t;let r=(t=n.size)!=null?t:$();return {...Xe(e,r,n.description),encode:i=>(typeof r=="number"&&Ye("array",r,i.length),w([Ge(r,i.length),...i.map(o=>e.encode(o))]))}}function xe(e={}){var o,s;let n=(o=e.size)!=null?o:"variable",r=typeof n=="object"?n.description:`${n}`,t=(s=e.description)!=null?s:`bytes(${r})`,i={description:t,encode:a=>a,fixedSize:null,maxSize:null};return n==="variable"?i:typeof n=="number"?k(i,n,t):{...i,encode:a=>{let c=i.encode(a),d=n.encode(c.length);return w([d,c])}}}function qe(e,n){let r=e.map(([t,i])=>`${String(t)}: ${i.description}`).join(", ");return {description:n!=null?n:`struct(${r})`,fixedSize:J(e.map(([,t])=>t.fixedSize)),maxSize:J(e.map(([,t])=>t.maxSize))}}function z(e,n={}){return {...qe(e,n.description),encode:r=>{let t=e.map(([i,o])=>o.encode(r[i]));return w(t)}}}var C=(e=>(e[e.WRITABLE_SIGNER=3]="WRITABLE_SIGNER",e[e.READONLY_SIGNER=2]="READONLY_SIGNER",e[e.WRITABLE=1]="WRITABLE",e[e.READONLY=0]="READONLY",e))(C||{}),Ze=1;function E(e){return e>=2}function B(e){return (e&Ze)!==0}function Ae(e,n){return e|n}function be(e,n,r){var t;e[n]=r((t=e[n])!=null?t:{role:C.READONLY});}var f=Symbol("AddressMapTypeProperty");function Je(e,n){let r={[e]:{[f]:0,role:C.WRITABLE_SIGNER}},t=new Set;for(let i of n){be(r,i.programAddress,s=>{if(t.add(i.programAddress),f in s){if(B(s.role))switch(s[f]){case 0:throw new Error(`This transaction includes an address (\`${i.programAddress}\`) which is both invoked and set as the fee payer. Program addresses may not pay fees.`);default:throw new Error(`This transaction includes an address (\`${i.programAddress}\`) which is both invoked and marked writable. Program addresses may not be writable.`)}if(s[f]===2)return s}return {[f]:2,role:C.READONLY}});let o;if(i.accounts)for(let s of i.accounts)be(r,s.address,a=>{let{address:c,...d}=s;if(f in a)switch(a[f]){case 0:return a;case 1:{let u=Ae(a.role,d.role);if("lookupTableAddress"in d){if(a.lookupTableAddress!==d.lookupTableAddress&&(o||(o=O()))(d.lookupTableAddress,a.lookupTableAddress)<0)return {[f]:1,...d,role:u}}else if(E(d.role))return {[f]:2,role:u};return a.role!==u?{...a,role:u}:a}case 2:{let u=Ae(a.role,d.role);if(t.has(s.address)){if(B(d.role))throw new Error(`This transaction includes an address (\`${s.address}\`) which is both invoked and marked writable. Program addresses may not be writable.`);return a.role!==u?{...a,role:u}:a}else return "lookupTableAddress"in d&&!E(a.role)?{...d,[f]:1,role:u}:a.role!==u?{...a,role:u}:a}}return "lookupTableAddress"in d?{...d,[f]:1}:{...d,[f]:2}});}return r}function Qe(e){let n;return Object.entries(e).sort(([t,i],[o,s])=>{if(i[f]!==s[f]){if(i[f]===0)return -1;if(s[f]===0)return 1;if(i[f]===2)return -1;if(s[f]===2)return 1}let a=E(i.role);if(a!==E(s.role))return a?-1:1;let c=B(i.role);return c!==B(s.role)?c?-1:1:(n||(n=O()),i[f]===1&&s[f]===1&&i.lookupTableAddress!==s.lookupTableAddress?n(i.lookupTableAddress,s.lookupTableAddress):n(t,o))}).map(([t,i])=>({address:t,...i}))}function en(e){var r;let n={};for(let t of e){if(!("lookupTableAddress"in t))continue;let i=n[r=t.lookupTableAddress]||(n[r]={readableIndices:[],writableIndices:[]});t.role===C.WRITABLE?i.writableIndices.push(t.addressIndex):i.readableIndices.push(t.addressIndex);}return Object.keys(n).sort(O()).map(t=>({lookupTableAddress:t,...n[t]}))}function nn(e){let n=0,r=0,t=0;for(let i of e){if("lookupTableAddress"in i)break;let o=B(i.role);E(i.role)?(t++,o||r++):o||n++;}return {numReadonlyNonSignerAccounts:n,numReadonlySignerAccounts:r,numSignerAccounts:t}}function rn(e){let n={};for(let[r,t]of e.entries())n[t.address]=r;return n}function tn(e,n){let r=rn(n);return e.map(({accounts:t,data:i,programAddress:o})=>({programAddressIndex:r[o],...t?{accountIndices:t.map(({address:s})=>r[s])}:null,...i?{data:i}:null}))}function on(e){return "nonce"in e?e.nonce:e.blockhash}function sn(e){let n=e.findIndex(t=>"lookupTableAddress"in t);return (n===-1?e:e.slice(0,n)).map(({address:t})=>t)}function an(e){let n=Je(e.feePayer,e.instructions),r=Qe(n);return {...e.version!=="legacy"?{addressTableLookups:en(r)}:null,header:nn(r),instructions:tn(e.instructions,r),lifetimeToken:on(e.lifetimeConstraint),staticAccounts:sn(r),version:e.version}}var cn="lookupTableAddress",dn="writableIndices",un="readableIndices",gn="addressTableLookup",Q;function fn(){return Q||(Q=z([["lookupTableAddress",Z({description:cn})],["writableIndices",T(y(),{description:dn,size:S()})],["readableIndices",T(y(),{description:un,size:S()})]],{description:gn})),Q}var ee;function ln(){return ee||(ee=y()),ee}function ne(e){let n=ln();return {...n,description:e!=null?e:n.description}}var mn=void 0,pn=void 0,Sn=void 0,yn=void 0;function hn(){return z([["numSignerAccounts",ne(mn)],["numReadonlySignerAccounts",ne(pn)],["numReadonlyNonSignerAccounts",ne(Sn)]],{description:yn})}var Tn="programAddressIndex",xn=void 0,An="accountIndices",bn="data",re;function wn(){return re||(re=v(z([["programAddressIndex",y({description:Tn})],["accountIndices",T(y({description:xn}),{description:An,size:S()})],["data",xe({description:bn,size:S()})]]),e=>{var n,r;return e.accountIndices!==void 0&&e.data!==void 0?e:{...e,accountIndices:(n=e.accountIndices)!=null?n:[],data:(r=e.data)!=null?r:new Uint8Array(0)}})),re}var zn=128,En={description:"",fixedSize:null,maxSize:1};function In(e){if(e==="legacy")return new Uint8Array;if(e<0||e>127)throw new Error(`Transaction version must be in the range [0, 127]. \`${e}\` given.`);return new Uint8Array([e|zn])}function vn(){return {...En,encode:In}}var Cn="staticAccounts",Bn="lifetimeToken",Dn="instructions",Mn="addressTableLookups";function kn(){return z(we())}function Pn(){return v(z([...we(),["addressTableLookups",$n()]]),e=>{var n;return e.version==="legacy"?e:{...e,addressTableLookups:(n=e.addressTableLookups)!=null?n:[]}})}function we(){return [["version",vn()],["header",hn()],["staticAccounts",T(Z(),{description:Cn,size:S()})],["lifetimeToken",N({description:Bn,encoding:U(),size:32})],["instructions",T(wn(),{description:Dn,size:S()})]]}function $n(){return T(fn(),{description:Mn,size:S()})}var Un="message";function Nn(){return {description:Un,encode:e=>e.version==="legacy"?kn().encode(e):Pn().encode(e),fixedSize:null,maxSize:null}}async function ze(e,n){let r=an(n),t="signatures"in n?{...n.signatures}:{},i=Nn().encode(r),o=await Promise.all(e.map(a=>Promise.all([R(a.publicKey),L(a.privateKey,i)])));for(let[a,c]of o)t[a]=c;let s={...n,signatures:t};return Object.freeze(s),s}function te(e){let n=e.instructions.flatMap(t=>{var i,o;return (o=(i=t.accounts)==null?void 0:i.filter(s=>E(s.role)))!=null?o:[]}).map(t=>t.address);new Set([e.feePayer,...n]).forEach(t=>{if(!e.signatures[t])throw new Error(`Transaction is missing signature for address \`${t}\``)});}function D(e){return "signMessages"in e&&typeof e.signMessages=="function"}function Ur(e){if(!D(e))throw new Error("The provided value does not implement the MessagePartialSigner interface")}function p(e){return "signTransactions"in e&&typeof e.signTransactions=="function"}function Rr(e){if(!p(e))throw new Error("The provided value does not implement the TransactionPartialSigner interface")}function On(e){return "keyPair"in e&&typeof e.keyPair=="object"&&D(e)&&p(e)}function Xr(e){if(!On(e))throw new Error("The provided value does not implement the KeyPairSigner interface")}async function Rn(e){let n=await R(e.publicKey);return Object.freeze({address:n,keyPair:e,signMessages:t=>Promise.all(t.map(async i=>Object.freeze({[n]:await L(e.privateKey,i.content)}))),signTransactions:t=>Promise.all(t.map(async i=>{let o=await ze([e],i);return Object.freeze({[n]:o.signatures[n]})}))})}async function qr(){return Rn(await he())}function ie(e){return pe(e.address)&&"modifyAndSignMessages"in e&&typeof e.modifyAndSignMessages=="function"}function nt(e){if(!ie(e))throw new Error("The provided value does not implement the MessageModifyingSigner interface")}function Ln(e){return D(e)||ie(e)}function ct(e){if(!Ln(e))throw new Error("The provided value does not implement any of the MessageSigner interfaces")}function gt(e){return Object.freeze({address:e,signMessages:async r=>r.map(()=>Object.freeze({})),signTransactions:async r=>r.map(()=>Object.freeze({}))})}function x(e){return "modifyAndSignTransactions"in e&&typeof e.modifyAndSignTransactions=="function"}function mt(e){if(!x(e))throw new Error("The provided value does not implement the TransactionModifyingSigner interface")}function M(e){return "signAndSendTransactions"in e&&typeof e.signAndSendTransactions=="function"}function yt(e){if(!M(e))throw new Error("The provided value does not implement the TransactionSendingSigner interface")}function F(e){return p(e)||x(e)||M(e)}function It(e){if(!F(e))throw new Error("The provided value does not implement any of the TransactionSigner interfaces")}async function Fn(e,n={}){var o;let r=(o=n.signers)!=null?o:[],{partialSigners:t,modifyingSigners:i}=Ee(A([..._(e).filter(F),...r]),{identifySendingSigner:!1});return Ie(e,i,t,n.abortSignal)}async function Vt(e,n={}){let r=await Fn(e,n);return te(r),r}async function Ht(e,n={}){var c;let r=(c=n.signers)!=null?c:[],t=n.abortSignal,{partialSigners:i,modifyingSigners:o,sendingSigner:s}=Ee(A([..._(e).filter(F),...r]));t==null||t.throwIfAborted();let a=await Ie(e,o,i,t);if(s){t==null||t.throwIfAborted();let[d]=await s.signAndSendTransactions([a],{abortSignal:t});return d}if(n.fallbackSender)return te(a),n.fallbackSender(a);throw new Error("No TransactionSendingSigner was identified and no fallback sender was provided.")}function Ee(e,n={}){var a;let t=((a=n.identifySendingSigner)!=null?a:!0)?_n(e):null,i=e.filter(c=>c!==t&&(x(c)||p(c))),o=Wn(i),s=i.filter(p).filter(c=>!o.includes(c));return Object.freeze({modifyingSigners:o,partialSigners:s,sendingSigner:t})}function _n(e){let n=e.filter(M);if(n.length===0)return null;let r=n.filter(t=>!x(t)&&!p(t));return r.length>0?r[0]:n[0]}function Wn(e){let n=e.filter(x);if(n.length===0)return [];let r=n.filter(t=>!p(t));return r.length>0?r:[n[0]]}async function Ie(e,n=[],r=[],t){var a;let i=await n.reduce(async(c,d)=>{t==null||t.throwIfAborted();let[u]=await d.modifyAndSignTransactions([await c],{abortSignal:t});return Object.freeze(u)},Promise.resolve(e));t==null||t.throwIfAborted();let o=await Promise.all(r.map(async c=>{let[d]=await c.signTransactions([i],{abortSignal:t});return d})),s={...i,signatures:Object.freeze(o.reduce((c,d)=>({...c,...d}),(a=i.signatures)!=null?a:{}))};return Object.freeze(s)}var ve=globalThis.TextEncoder;function Qt(e,n={}){return Object.freeze({content:typeof e=="string"?new ve().encode(e):e,signatures:Object.freeze({...n})})} | ||
exports.assertIsKeyPairSigner = Mr; | ||
exports.assertIsMessageModifyingSigner = Or; | ||
exports.assertIsMessagePartialSigner = yr; | ||
exports.assertIsMessageSigner = Hr; | ||
exports.assertIsTransactionModifyingSigner = nt; | ||
exports.assertIsTransactionPartialSigner = Ar; | ||
exports.assertIsTransactionSendingSigner = it; | ||
exports.assertIsTransactionSigner = gt; | ||
exports.createSignableMessage = Jr; | ||
exports.createSignerFromKeyPair = Dn; | ||
exports.generateKeyPairSigner = $r; | ||
exports.isKeyPairSigner = In; | ||
exports.isMessageModifyingSigner = J; | ||
exports.isMessagePartialSigner = I; | ||
exports.isMessageSigner = Cn; | ||
exports.isTransactionModifyingSigner = Q; | ||
exports.isTransactionPartialSigner = D; | ||
exports.isTransactionSendingSigner = ee; | ||
exports.isTransactionSigner = Bn; | ||
exports.assertIsKeyPairSigner = Xr; | ||
exports.assertIsMessageModifyingSigner = nt; | ||
exports.assertIsMessagePartialSigner = Ur; | ||
exports.assertIsMessageSigner = ct; | ||
exports.assertIsTransactionModifyingSigner = mt; | ||
exports.assertIsTransactionPartialSigner = Rr; | ||
exports.assertIsTransactionSendingSigner = yt; | ||
exports.assertIsTransactionSigner = It; | ||
exports.createNoopSigner = gt; | ||
exports.createSignableMessage = Qt; | ||
exports.createSignerFromKeyPair = Rn; | ||
exports.generateKeyPairSigner = qr; | ||
exports.getSignersFromInstruction = De; | ||
exports.getSignersFromTransaction = _; | ||
exports.isKeyPairSigner = On; | ||
exports.isMessageModifyingSigner = ie; | ||
exports.isMessagePartialSigner = D; | ||
exports.isMessageSigner = Ln; | ||
exports.isTransactionModifyingSigner = x; | ||
exports.isTransactionPartialSigner = p; | ||
exports.isTransactionSendingSigner = M; | ||
exports.isTransactionSigner = F; | ||
exports.partiallySignTransactionWithSigners = Fn; | ||
exports.signAndSendTransactionWithSigners = Ht; | ||
exports.signTransactionWithSigners = Vt; | ||
@@ -32,0 +38,0 @@ return exports; |
@@ -0,1 +1,2 @@ | ||
export * from './account-signer-meta'; | ||
export * from './keypair-signer'; | ||
@@ -5,2 +6,4 @@ export * from './message-modifying-signer'; | ||
export * from './message-signer'; | ||
export * from './noop-signer'; | ||
export * from './sign-transaction'; | ||
export * from './signable-message'; | ||
@@ -7,0 +10,0 @@ export * from './transaction-modifying-signer'; |
import { Address } from '@solana/addresses'; | ||
import { SignableMessage } from './signable-message'; | ||
import { BaseSignerConfig } from './types'; | ||
export type MessageModifyingSignerConfig = BaseSignerConfig; | ||
/** Defines a signer capable of signing messages. */ | ||
export type MessageModifyingSigner<TAddress extends string = string> = Readonly<{ | ||
address: Address<TAddress>; | ||
modifyAndSignMessages(messages: readonly SignableMessage[]): Promise<readonly SignableMessage[]>; | ||
modifyAndSignMessages(messages: readonly SignableMessage[], config?: MessageModifyingSignerConfig): Promise<readonly SignableMessage[]>; | ||
}>; | ||
@@ -8,0 +10,0 @@ /** Checks whether the provided value implements the {@link MessageModifyingSigner} interface. */ |
import { Address } from '@solana/addresses'; | ||
import { SignableMessage } from './signable-message'; | ||
import { SignatureDictionary } from './types'; | ||
import { BaseSignerConfig, SignatureDictionary } from './types'; | ||
export type MessagePartialSignerConfig = BaseSignerConfig; | ||
/** Defines a signer capable of signing messages. */ | ||
export type MessagePartialSigner<TAddress extends string = string> = Readonly<{ | ||
address: Address<TAddress>; | ||
signMessages(messages: readonly SignableMessage[]): Promise<readonly SignatureDictionary[]>; | ||
signMessages(messages: readonly SignableMessage[], config?: MessagePartialSignerConfig): Promise<readonly SignatureDictionary[]>; | ||
}>; | ||
@@ -9,0 +10,0 @@ /** Checks whether the provided value implements the {@link MessagePartialSigner} interface. */ |
import { Address } from '@solana/addresses'; | ||
import { CompilableTransaction } from '@solana/transactions'; | ||
import { BaseSignerConfig } from './types'; | ||
export type TransactionModifyingSignerConfig = BaseSignerConfig; | ||
/** Defines a signer capable of signing transactions. */ | ||
export type TransactionModifyingSigner<TAddress extends string = string> = Readonly<{ | ||
address: Address<TAddress>; | ||
modifyAndSignTransactions<TTransaction extends CompilableTransaction>(transactions: readonly TTransaction[]): Promise<readonly TTransaction[]>; | ||
modifyAndSignTransactions<TTransaction extends CompilableTransaction>(transactions: readonly TTransaction[], config?: TransactionModifyingSignerConfig): Promise<readonly TTransaction[]>; | ||
}>; | ||
@@ -8,0 +10,0 @@ /** Checks whether the provided value implements the {@link TransactionModifyingSigner} interface. */ |
import { Address } from '@solana/addresses'; | ||
import { CompilableTransaction } from '@solana/transactions'; | ||
import { SignatureDictionary } from './types'; | ||
import { BaseSignerConfig, SignatureDictionary } from './types'; | ||
export type TransactionPartialSignerConfig = BaseSignerConfig; | ||
/** Defines a signer capable of signing transactions. */ | ||
export type TransactionPartialSigner<TAddress extends string = string> = Readonly<{ | ||
address: Address<TAddress>; | ||
signTransactions(transactions: readonly CompilableTransaction[]): Promise<readonly SignatureDictionary[]>; | ||
signTransactions(transactions: readonly CompilableTransaction[], config?: TransactionPartialSignerConfig): Promise<readonly SignatureDictionary[]>; | ||
}>; | ||
@@ -9,0 +10,0 @@ /** Checks whether the provided value implements the {@link TransactionPartialSigner} interface. */ |
import { Address } from '@solana/addresses'; | ||
import { SignatureBytes } from '@solana/keys'; | ||
import { CompilableTransaction } from '@solana/transactions'; | ||
import { BaseSignerConfig } from './types'; | ||
export type TransactionSendingSignerConfig = BaseSignerConfig; | ||
/** Defines a signer capable of signing and sending transactions simultaneously. */ | ||
export type TransactionSendingSigner<TAddress extends string = string> = Readonly<{ | ||
address: Address<TAddress>; | ||
signAndSendTransactions(transactions: readonly CompilableTransaction[]): Promise<readonly SignatureBytes[]>; | ||
signAndSendTransactions(transactions: readonly CompilableTransaction[], config?: TransactionSendingSignerConfig): Promise<readonly SignatureBytes[]>; | ||
}>; | ||
@@ -9,0 +11,0 @@ /** Checks whether the provided value implements the {@link TransactionSendingSigner} interface. */ |
import { Address } from '@solana/addresses'; | ||
import { SignatureBytes } from '@solana/keys'; | ||
export type SignatureDictionary = Readonly<Record<Address, SignatureBytes>>; | ||
export type BaseSignerConfig = Readonly<{ | ||
abortSignal?: AbortSignal; | ||
}>; | ||
//# sourceMappingURL=types.d.ts.map |
{ | ||
"name": "@solana/signers", | ||
"version": "2.0.0-experimental.3331786", | ||
"version": "2.0.0-experimental.0eb69ae", | ||
"description": "An abstraction layer over signing messages and transactions in Solana", | ||
@@ -52,5 +52,6 @@ "exports": { | ||
"dependencies": { | ||
"@solana/addresses": "2.0.0-development", | ||
"@solana/keys": "2.0.0-development", | ||
"@solana/transactions": "2.0.0-development" | ||
"@solana/addresses": "2.0.0-experimental.0eb69ae", | ||
"@solana/instructions": "2.0.0-experimental.0eb69ae", | ||
"@solana/keys": "2.0.0-experimental.0eb69ae", | ||
"@solana/transactions": "2.0.0-experimental.0eb69ae" | ||
}, | ||
@@ -72,7 +73,7 @@ "devDependencies": { | ||
"prettier": "^2.8", | ||
"tsup": "7.2.0", | ||
"tsup": "^8.0.1", | ||
"typescript": "^5.2.2", | ||
"version-from-git": "^1.1.1", | ||
"build-scripts": "0.0.0", | ||
"test-config": "0.0.0", | ||
"build-scripts": "0.0.0", | ||
"test-matchers": "0.0.0", | ||
@@ -79,0 +80,0 @@ "text-encoding-impl": "0.0.0", |
171
README.md
@@ -339,10 +339,4 @@ [![npm][npm-image]][npm-url] | ||
### Functions | ||
For a given address, a Noop (No-Operation) signer can be created to offer an implementation of both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces such that they do not sign anything. Namely, signing a transaction or a message with a `NoopSigner` will return an empty `SignatureDictionary`. | ||
#### `createNoopSigner()` | ||
_Coming soon..._ | ||
Creates a Noop (No-Operation) signer from a given address. It will return an implementation of both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces that do not sign anything. Namely, signing a transaction or a message will return an empty `SignatureDictionary`. | ||
This signer may be useful: | ||
@@ -353,8 +347,26 @@ | ||
### Types | ||
#### `NoopSigner<TAddress>` | ||
Defines a Noop (No-Operation) signer. | ||
```ts | ||
const myNoopSigner: NoopSigner; | ||
myNoopSigner satisfies MessagePartialSigner; | ||
myNoopSigner satisfies TransactionPartialSigner; | ||
``` | ||
### Functions | ||
#### `createNoopSigner()` | ||
Creates a Noop (No-Operation) signer from a given address. | ||
```ts | ||
import { createNoopSigner } from '@solana/signers'; | ||
const myAddress = address('1234..5678'); | ||
const myNoopSigner = createNoopSigner(myAddress); | ||
// ^ MessagePartialSigner<'1234..5678'> & TransactionPartialSigner<'1234..5678'> | ||
const myNoopSigner = createNoopSigner(address('1234..5678')); | ||
const [myMessageSignatures] = await myNoopSigner.signMessages([myMessage]); // <- Empty signature dictionary. | ||
const [myTransactionSignatures] = await myNoopSigner.signTransactions([myTransaction]); // <- Empty signature dictionary. | ||
``` | ||
@@ -364,8 +376,143 @@ | ||
This package defines an alternative definition for account metas that allows us to store `TransactionSigners` inside them. This means each instruction can keep track of its own set of signers and, by extension, so can transactions. | ||
It also provides helper functions that deduplicate and extract signers from instructions and transactions which makes it possible to sign an entire transaction automatically as we will see in the next section. | ||
### Types | ||
_Coming soon..._ | ||
#### `IAccountSignerMeta` | ||
Alternative `IAccountMeta` definition for signer accounts that allows us to store `TransactionSigners` inside it. | ||
```ts | ||
const mySignerMeta: IAccountSignerMeta = { | ||
address: myTransactionSigner.address, | ||
role: AccountRole.READONLY_SIGNER, | ||
signer: myTransactionSigner, | ||
}; | ||
``` | ||
#### `IInstructionWithSigners` | ||
Extends the `IInstruction` type to allow `IAccountSignerMetas` to be used inside the instruction's `accounts` array. | ||
```ts | ||
const myInstructionWithSigners: IInstructionWithSigners = { | ||
programAddress: address('1234..5678'), | ||
accounts: [ | ||
{ | ||
address: myTransactionSigner.address, | ||
role: AccountRole.READONLY_SIGNER, | ||
signer: myTransactionSigner, | ||
}, | ||
], | ||
}; | ||
``` | ||
### Functions | ||
_Coming soon..._ | ||
#### `getSignersFromInstruction()` | ||
Extracts and deduplicates all signers stored inside the account metas of an instruction. | ||
```ts | ||
const mySignerA = { address: address('1111..1111'), signTransactions: async () => {} }; | ||
const mySignerB = { address: address('2222..2222'), signTransactions: async () => {} }; | ||
const myInstructionWithSigners: IInstructionWithSigners = { | ||
programAddress: address('1234..5678'), | ||
accounts: [ | ||
{ address: mySignerA.address, role: AccountRole.READONLY_SIGNER, signer: mySignerA }, | ||
{ address: mySignerB.address, role: AccountRole.WRITABLE_SIGNER, signer: mySignerB }, | ||
{ address: mySignerA.address, role: AccountRole.WRITABLE_SIGNER, signer: mySignerA }, | ||
], | ||
}; | ||
const instructionSigners = getSignersFromInstruction(myInstructionWithSigners); | ||
// ^ [mySignerA, mySignerB] | ||
``` | ||
#### `getSignersFromTransaction()` | ||
Similarly to `getSignersFromInstruction`, this function extracts and deduplicates all signers stored inside the account metas of all the instructions inside a transaction. | ||
```ts | ||
const transactionSigners = getSignersFromTransaction(myTransactionWithSigners); | ||
``` | ||
## Signing transactions with signers | ||
As we've seen in the previous section, we can store and extract `TransactionSigners` from instructions and transactions. This allows us to provide helper methods that sign transactions using the signers stored inside them. | ||
### Functions | ||
#### `partiallySignTransactionWithSigners()` | ||
Extracts all signers inside the provided transaction and uses them to sign it. It first uses all `TransactionModifyingSigners` sequentially before using all `TransactionPartialSigners` in parallel. | ||
If a composite signer implements both interfaces, it will be used as a modifying signer if no other signer implements that interface. Otherwise, it will be used as a partial signer. | ||
```ts | ||
const mySignedTransaction = partiallySignTransactionWithSigners(myTransaction); | ||
``` | ||
It also accepts an optional `AbortSignal` and an additional array of signers that will be merged with the ones extracted from the transaction, if any. | ||
```ts | ||
const mySignedTransaction = partiallySignTransactionWithSigners(myTransaction, { | ||
abortSignal: myAbortController.signal, | ||
signers: [myOtherSigner], | ||
}); | ||
``` | ||
Finally, note that this function ignores `TransactionSendingSigners` as it does not send the transaction. See the `signAndSendTransactionWithSigners` function below for more details on how to use sending signers. | ||
#### `signTransactionWithSigners()` | ||
This function works the same as the `partiallySignTransactionWithSigners` function described above except that it also ensures the transaction is fully signed before returning it. An error will be thrown if that's not the case. | ||
```ts | ||
const mySignedTransaction = signTransactionWithSigners(myTransaction); | ||
// With additional config. | ||
const mySignedTransaction = signTransactionWithSigners(myTransaction, { | ||
abortSignal: myAbortController.signal, | ||
signers: [myOtherSigner], | ||
}); | ||
// We now know the transaction is fully signed. | ||
mySignedTransaction satisfies IFullySignedTransaction; | ||
``` | ||
#### `signAndSendTransactionWithSigners()` | ||
Extracts all signers inside the provided transaction and uses them to sign it before sending it immediately to the blockchain. It returns the signature of the sent transaction (i.e. its identifier). | ||
```ts | ||
const myTransactionSignature = signAndSendTransactionWithSigners(myTransaction); | ||
// With additional config. | ||
const myTransactionSignature = signAndSendTransactionWithSigners(myTransaction, { | ||
abortSignal: myAbortController.signal, | ||
signers: [myOtherSigner], | ||
}); | ||
``` | ||
Similarly to the `partiallySignTransactionWithSigners` function, it first uses all `TransactionModifyingSigners` sequentially before using all `TransactionPartialSigners` in parallel. It then sends the transaction using the first `TransactionSendingSigner` it finds. Any other sending signer that does not implement another transaction signer interface will be ignored. | ||
If no `TransactionSendingSigner` is extracted from the transaction or explicitly provided, the `fallbackSender` third argument will be used to send the transaction. If no fallback sender is provided and no sending signer is identified, an error will be thrown. | ||
```ts | ||
const fallbackSender = async (transaction: CompilableTransaction) => { | ||
const encodedTransaction = getBase64EncodedWireTransaction(transaction); | ||
const signature = await rpc.sendTransaction(encodedTransaction).send(); | ||
return getBase58Encoder().encode(signature); | ||
}; | ||
const myTransactionSignature = signAndSendTransactionWithSigners(myTransaction, { fallbackSender }); | ||
``` | ||
Here as well, composite transaction signers are treated such that at least one sending signer is used if any. When a `TransactionSigner` implements more than one interface, use it as a: | ||
- `TransactionSendingSigner`, if no other `TransactionSendingSigner` exist. | ||
- `TransactionModifyingSigner`, if no other `TransactionModifyingSigner` exist. | ||
- `TransactionPartialSigner`, otherwise. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
543476
47
3123
516
4
+ Added@solana/addresses@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/assertions@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/codecs-core@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/codecs-data-structures@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/codecs-numbers@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/codecs-strings@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/functional@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/instructions@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/keys@2.0.0-experimental.0eb69ae(transitive)
+ Added@solana/transactions@2.0.0-experimental.0eb69ae(transitive)
+ Addedfastestsmallesttextencoderdecoder@1.0.22(transitive)