@solana/signers
Advanced tools
Comparing version 2.0.0-experimental.699bde0 to 2.0.0-experimental.819422a
@@ -0,7 +1,56 @@ | ||
import { isSignerRole } from '@solana/instructions'; | ||
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; | ||
} else if (deduplicated[signer.address] !== signer) { | ||
throw new Error( | ||
`Multiple distinct signers were identified for address "${signer.address}". Please ensure that you are using the same signer instance for each address.` | ||
); | ||
} | ||
}); | ||
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)); | ||
} | ||
function addSignersToInstruction(signers, instruction) { | ||
if (!instruction.accounts || instruction.accounts.length === 0) { | ||
return instruction; | ||
} | ||
const signerByAddress = new Map(deduplicateSigners(signers).map((signer) => [signer.address, signer])); | ||
return Object.freeze({ | ||
...instruction, | ||
accounts: instruction.accounts.map((account) => { | ||
const signer = signerByAddress.get(account.address); | ||
if (!isSignerRole(account.role) || "signer" in account || !signer) { | ||
return account; | ||
} | ||
return Object.freeze({ ...account, signer }); | ||
}) | ||
}); | ||
} | ||
function addSignersToTransaction(signers, transaction) { | ||
if (transaction.instructions.length === 0) { | ||
return transaction; | ||
} | ||
return Object.freeze({ | ||
...transaction, | ||
instructions: transaction.instructions.map((instruction) => addSignersToInstruction(signers, instruction)) | ||
}); | ||
} | ||
// src/message-partial-signer.ts | ||
@@ -76,10 +125,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 +167,128 @@ | ||
export { assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner }; | ||
//# sourceMappingURL=out.js.map | ||
//# sourceMappingURL=index.browser.js.map | ||
// src/sign-transaction.ts | ||
async function partiallySignTransactionWithSigners(transaction, config = {}) { | ||
const { partialSigners, modifyingSigners } = categorizeTransactionSigners( | ||
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)), | ||
{ 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 abortSignal = config.abortSignal; | ||
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( | ||
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)) | ||
); | ||
abortSignal?.throwIfAborted(); | ||
const signedTransaction = await signModifyingAndPartialTransactionSigners( | ||
transaction, | ||
modifyingSigners, | ||
partialSigners, | ||
abortSignal | ||
); | ||
if (!sendingSigner) { | ||
throw new Error( | ||
"No `TransactionSendingSigner` was identified. Please provide a valid `ITransactionWithSingleSendingSigner` transaction." | ||
); | ||
} | ||
abortSignal?.throwIfAborted(); | ||
const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); | ||
abortSignal?.throwIfAborted(); | ||
return signature; | ||
} | ||
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 }) | ||
}); | ||
} | ||
// src/transaction-with-single-sending-signer.ts | ||
function isTransactionWithSingleSendingSigner(transaction) { | ||
try { | ||
assertIsTransactionWithSingleSendingSigner(transaction); | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
function assertIsTransactionWithSingleSendingSigner(transaction) { | ||
const signers = getSignersFromTransaction(transaction); | ||
const sendingSigners = signers.filter(isTransactionSendingSigner); | ||
if (sendingSigners.length === 0) { | ||
const error = new Error("No `TransactionSendingSigner` was identified."); | ||
error.name = "MissingTransactionSendingSignerError"; | ||
throw error; | ||
} | ||
const sendingOnlySigners = sendingSigners.filter( | ||
(signer) => !isTransactionPartialSigner(signer) && !isTransactionModifyingSigner(signer) | ||
); | ||
if (sendingOnlySigners.length > 1) { | ||
const error = new Error("More than one `TransactionSendingSigner` was identified."); | ||
error.name = "MultipleTransactionSendingSignersError"; | ||
throw error; | ||
} | ||
} | ||
export { addSignersToInstruction, addSignersToTransaction, assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, assertIsTransactionWithSingleSendingSigner, createNoopSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, getSignersFromInstruction, getSignersFromTransaction, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner, isTransactionWithSingleSendingSigner, partiallySignTransactionWithSigners, signAndSendTransactionWithSigners, signTransactionWithSigners }; |
@@ -5,2 +5,60 @@ this.globalThis = this.globalThis || {}; | ||
// src/deduplicate-signers.ts | ||
function deduplicateSigners(signers) { | ||
const deduplicated = {}; | ||
signers.forEach((signer) => { | ||
if (!deduplicated[signer.address]) { | ||
deduplicated[signer.address] = signer; | ||
} else if (deduplicated[signer.address] !== signer) { | ||
throw new Error( | ||
`Multiple distinct signers were identified for address "${signer.address}". Please ensure that you are using the same signer instance for each address.` | ||
); | ||
} | ||
}); | ||
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)); | ||
} | ||
// ../instructions/dist/index.browser.js | ||
function isSignerRole(role) { | ||
return role >= 2; | ||
} | ||
// src/add-signers.ts | ||
function addSignersToInstruction(signers, instruction) { | ||
if (!instruction.accounts || instruction.accounts.length === 0) { | ||
return instruction; | ||
} | ||
const signerByAddress = new Map(deduplicateSigners(signers).map((signer) => [signer.address, signer])); | ||
return Object.freeze({ | ||
...instruction, | ||
accounts: instruction.accounts.map((account) => { | ||
const signer = signerByAddress.get(account.address); | ||
if (!isSignerRole(account.role) || "signer" in account || !signer) { | ||
return account; | ||
} | ||
return Object.freeze({ ...account, signer }); | ||
}) | ||
}); | ||
} | ||
function addSignersToTransaction(signers, transaction) { | ||
if (transaction.instructions.length === 0) { | ||
return transaction; | ||
} | ||
return Object.freeze({ | ||
...transaction, | ||
instructions: transaction.instructions.map((instruction) => addSignersToInstruction(signers, instruction)) | ||
}); | ||
} | ||
// ../codecs-core/dist/index.browser.js | ||
@@ -605,3 +663,3 @@ function assertByteArrayIsNotEmptyForCodec(codecDescription, bytes, offset = 0) { | ||
var IS_WRITABLE_BITMASK = 1; | ||
function isSignerRole(role) { | ||
function isSignerRole2(role) { | ||
return role >= 2; | ||
@@ -680,3 +738,3 @@ } | ||
} | ||
} else if (isSignerRole(accountMeta.role)) { | ||
} else if (isSignerRole2(accountMeta.role)) { | ||
return { | ||
@@ -718,3 +776,3 @@ [TYPE]: 2, | ||
// long as they are not require to sign the transaction. | ||
!isSignerRole(entry.role)) { | ||
!isSignerRole2(entry.role)) { | ||
return { | ||
@@ -770,4 +828,4 @@ ...accountMeta, | ||
} | ||
const leftIsSigner = isSignerRole(leftEntry.role); | ||
if (leftIsSigner !== isSignerRole(rightEntry.role)) { | ||
const leftIsSigner = isSignerRole2(leftEntry.role); | ||
if (leftIsSigner !== isSignerRole2(rightEntry.role)) { | ||
return leftIsSigner ? -1 : 1; | ||
@@ -822,3 +880,3 @@ } | ||
const accountIsWritable = isWritableRole(account.role); | ||
if (isSignerRole(account.role)) { | ||
if (isSignerRole2(account.role)) { | ||
numSignerAccounts++; | ||
@@ -1086,2 +1144,14 @@ if (!accountIsWritable) { | ||
} | ||
function assertTransactionIsFullySigned(transaction) { | ||
const signerAddressesFromInstructions = transaction.instructions.flatMap((i) => { | ||
var _a, _b; | ||
return (_b = (_a = i.accounts) == null ? void 0 : _a.filter((a) => isSignerRole2(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 +1229,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 +1271,132 @@ | ||
// src/sign-transaction.ts | ||
async function partiallySignTransactionWithSigners(transaction, config = {}) { | ||
const { partialSigners, modifyingSigners } = categorizeTransactionSigners( | ||
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)), | ||
{ 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 abortSignal = config.abortSignal; | ||
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( | ||
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)) | ||
); | ||
abortSignal == null ? void 0 : abortSignal.throwIfAborted(); | ||
const signedTransaction = await signModifyingAndPartialTransactionSigners( | ||
transaction, | ||
modifyingSigners, | ||
partialSigners, | ||
abortSignal | ||
); | ||
if (!sendingSigner) { | ||
throw new Error( | ||
"No `TransactionSendingSigner` was identified. Please provide a valid `ITransactionWithSingleSendingSigner` transaction." | ||
); | ||
} | ||
abortSignal == null ? void 0 : abortSignal.throwIfAborted(); | ||
const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); | ||
abortSignal == null ? void 0 : abortSignal.throwIfAborted(); | ||
return signature; | ||
} | ||
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 }) | ||
}); | ||
} | ||
// src/transaction-with-single-sending-signer.ts | ||
function isTransactionWithSingleSendingSigner(transaction) { | ||
try { | ||
assertIsTransactionWithSingleSendingSigner(transaction); | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
function assertIsTransactionWithSingleSendingSigner(transaction) { | ||
const signers = getSignersFromTransaction(transaction); | ||
const sendingSigners = signers.filter(isTransactionSendingSigner); | ||
if (sendingSigners.length === 0) { | ||
const error = new Error("No `TransactionSendingSigner` was identified."); | ||
error.name = "MissingTransactionSendingSignerError"; | ||
throw error; | ||
} | ||
const sendingOnlySigners = sendingSigners.filter( | ||
(signer) => !isTransactionPartialSigner(signer) && !isTransactionModifyingSigner(signer) | ||
); | ||
if (sendingOnlySigners.length > 1) { | ||
const error = new Error("More than one `TransactionSendingSigner` was identified."); | ||
error.name = "MultipleTransactionSendingSignersError"; | ||
throw error; | ||
} | ||
} | ||
exports.addSignersToInstruction = addSignersToInstruction; | ||
exports.addSignersToTransaction = addSignersToTransaction; | ||
exports.assertIsKeyPairSigner = assertIsKeyPairSigner; | ||
@@ -1209,5 +1410,9 @@ exports.assertIsMessageModifyingSigner = assertIsMessageModifyingSigner; | ||
exports.assertIsTransactionSigner = assertIsTransactionSigner; | ||
exports.assertIsTransactionWithSingleSendingSigner = assertIsTransactionWithSingleSendingSigner; | ||
exports.createNoopSigner = createNoopSigner; | ||
exports.createSignableMessage = createSignableMessage; | ||
exports.createSignerFromKeyPair = createSignerFromKeyPair; | ||
exports.generateKeyPairSigner = generateKeyPairSigner; | ||
exports.getSignersFromInstruction = getSignersFromInstruction; | ||
exports.getSignersFromTransaction = getSignersFromTransaction; | ||
exports.isKeyPairSigner = isKeyPairSigner; | ||
@@ -1221,2 +1426,6 @@ exports.isMessageModifyingSigner = isMessageModifyingSigner; | ||
exports.isTransactionSigner = isTransactionSigner; | ||
exports.isTransactionWithSingleSendingSigner = isTransactionWithSingleSendingSigner; | ||
exports.partiallySignTransactionWithSigners = partiallySignTransactionWithSigners; | ||
exports.signAndSendTransactionWithSigners = signAndSendTransactionWithSigners; | ||
exports.signTransactionWithSigners = signTransactionWithSigners; | ||
@@ -1223,0 +1432,0 @@ return exports; |
@@ -0,7 +1,56 @@ | ||
import { isSignerRole } from '@solana/instructions'; | ||
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; | ||
} else if (deduplicated[signer.address] !== signer) { | ||
throw new Error( | ||
`Multiple distinct signers were identified for address "${signer.address}". Please ensure that you are using the same signer instance for each address.` | ||
); | ||
} | ||
}); | ||
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)); | ||
} | ||
function addSignersToInstruction(signers, instruction) { | ||
if (!instruction.accounts || instruction.accounts.length === 0) { | ||
return instruction; | ||
} | ||
const signerByAddress = new Map(deduplicateSigners(signers).map((signer) => [signer.address, signer])); | ||
return Object.freeze({ | ||
...instruction, | ||
accounts: instruction.accounts.map((account) => { | ||
const signer = signerByAddress.get(account.address); | ||
if (!isSignerRole(account.role) || "signer" in account || !signer) { | ||
return account; | ||
} | ||
return Object.freeze({ ...account, signer }); | ||
}) | ||
}); | ||
} | ||
function addSignersToTransaction(signers, transaction) { | ||
if (transaction.instructions.length === 0) { | ||
return transaction; | ||
} | ||
return Object.freeze({ | ||
...transaction, | ||
instructions: transaction.instructions.map((instruction) => addSignersToInstruction(signers, instruction)) | ||
}); | ||
} | ||
// src/message-partial-signer.ts | ||
@@ -76,10 +125,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 +167,130 @@ | ||
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 { partialSigners, modifyingSigners } = categorizeTransactionSigners( | ||
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)), | ||
{ 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 abortSignal = config.abortSignal; | ||
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( | ||
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)) | ||
); | ||
abortSignal?.throwIfAborted(); | ||
const signedTransaction = await signModifyingAndPartialTransactionSigners( | ||
transaction, | ||
modifyingSigners, | ||
partialSigners, | ||
abortSignal | ||
); | ||
if (!sendingSigner) { | ||
throw new Error( | ||
"No `TransactionSendingSigner` was identified. Please provide a valid `ITransactionWithSingleSendingSigner` transaction." | ||
); | ||
} | ||
abortSignal?.throwIfAborted(); | ||
const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); | ||
abortSignal?.throwIfAborted(); | ||
return signature; | ||
} | ||
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 }) | ||
}); | ||
} | ||
// src/transaction-with-single-sending-signer.ts | ||
function isTransactionWithSingleSendingSigner(transaction) { | ||
try { | ||
assertIsTransactionWithSingleSendingSigner(transaction); | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
function assertIsTransactionWithSingleSendingSigner(transaction) { | ||
const signers = getSignersFromTransaction(transaction); | ||
const sendingSigners = signers.filter(isTransactionSendingSigner); | ||
if (sendingSigners.length === 0) { | ||
const error = new Error("No `TransactionSendingSigner` was identified."); | ||
error.name = "MissingTransactionSendingSignerError"; | ||
throw error; | ||
} | ||
const sendingOnlySigners = sendingSigners.filter( | ||
(signer) => !isTransactionPartialSigner(signer) && !isTransactionModifyingSigner(signer) | ||
); | ||
if (sendingOnlySigners.length > 1) { | ||
const error = new Error("More than one `TransactionSendingSigner` was identified."); | ||
error.name = "MultipleTransactionSendingSignersError"; | ||
throw error; | ||
} | ||
} | ||
export { addSignersToInstruction, addSignersToTransaction, assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, assertIsTransactionWithSingleSendingSigner, createNoopSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, getSignersFromInstruction, getSignersFromTransaction, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner, isTransactionWithSingleSendingSigner, partiallySignTransactionWithSigners, signAndSendTransactionWithSigners, signTransactionWithSigners }; | ||
//# sourceMappingURL=out.js.map | ||
//# sourceMappingURL=index.native.js.map |
@@ -0,7 +1,56 @@ | ||
import { isSignerRole } from '@solana/instructions'; | ||
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; | ||
} else if (deduplicated[signer.address] !== signer) { | ||
throw new Error( | ||
`Multiple distinct signers were identified for address "${signer.address}". Please ensure that you are using the same signer instance for each address.` | ||
); | ||
} | ||
}); | ||
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)); | ||
} | ||
function addSignersToInstruction(signers, instruction) { | ||
if (!instruction.accounts || instruction.accounts.length === 0) { | ||
return instruction; | ||
} | ||
const signerByAddress = new Map(deduplicateSigners(signers).map((signer) => [signer.address, signer])); | ||
return Object.freeze({ | ||
...instruction, | ||
accounts: instruction.accounts.map((account) => { | ||
const signer = signerByAddress.get(account.address); | ||
if (!isSignerRole(account.role) || "signer" in account || !signer) { | ||
return account; | ||
} | ||
return Object.freeze({ ...account, signer }); | ||
}) | ||
}); | ||
} | ||
function addSignersToTransaction(signers, transaction) { | ||
if (transaction.instructions.length === 0) { | ||
return transaction; | ||
} | ||
return Object.freeze({ | ||
...transaction, | ||
instructions: transaction.instructions.map((instruction) => addSignersToInstruction(signers, instruction)) | ||
}); | ||
} | ||
// src/message-partial-signer.ts | ||
@@ -76,10 +125,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 +167,130 @@ | ||
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 { partialSigners, modifyingSigners } = categorizeTransactionSigners( | ||
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)), | ||
{ 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 abortSignal = config.abortSignal; | ||
const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners( | ||
deduplicateSigners(getSignersFromTransaction(transaction).filter(isTransactionSigner)) | ||
); | ||
abortSignal?.throwIfAborted(); | ||
const signedTransaction = await signModifyingAndPartialTransactionSigners( | ||
transaction, | ||
modifyingSigners, | ||
partialSigners, | ||
abortSignal | ||
); | ||
if (!sendingSigner) { | ||
throw new Error( | ||
"No `TransactionSendingSigner` was identified. Please provide a valid `ITransactionWithSingleSendingSigner` transaction." | ||
); | ||
} | ||
abortSignal?.throwIfAborted(); | ||
const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], { abortSignal }); | ||
abortSignal?.throwIfAborted(); | ||
return signature; | ||
} | ||
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 }) | ||
}); | ||
} | ||
// src/transaction-with-single-sending-signer.ts | ||
function isTransactionWithSingleSendingSigner(transaction) { | ||
try { | ||
assertIsTransactionWithSingleSendingSigner(transaction); | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
} | ||
function assertIsTransactionWithSingleSendingSigner(transaction) { | ||
const signers = getSignersFromTransaction(transaction); | ||
const sendingSigners = signers.filter(isTransactionSendingSigner); | ||
if (sendingSigners.length === 0) { | ||
const error = new Error("No `TransactionSendingSigner` was identified."); | ||
error.name = "MissingTransactionSendingSignerError"; | ||
throw error; | ||
} | ||
const sendingOnlySigners = sendingSigners.filter( | ||
(signer) => !isTransactionPartialSigner(signer) && !isTransactionModifyingSigner(signer) | ||
); | ||
if (sendingOnlySigners.length > 1) { | ||
const error = new Error("More than one `TransactionSendingSigner` was identified."); | ||
error.name = "MultipleTransactionSendingSignersError"; | ||
throw error; | ||
} | ||
} | ||
export { addSignersToInstruction, addSignersToTransaction, assertIsKeyPairSigner, assertIsMessageModifyingSigner, assertIsMessagePartialSigner, assertIsMessageSigner, assertIsTransactionModifyingSigner, assertIsTransactionPartialSigner, assertIsTransactionSendingSigner, assertIsTransactionSigner, assertIsTransactionWithSingleSendingSigner, createNoopSigner, createSignableMessage, createSignerFromKeyPair, generateKeyPairSigner, getSignersFromInstruction, getSignersFromTransaction, isKeyPairSigner, isMessageModifyingSigner, isMessagePartialSigner, isMessageSigner, isTransactionModifyingSigner, isTransactionPartialSigner, isTransactionSendingSigner, isTransactionSigner, isTransactionWithSingleSendingSigner, partiallySignTransactionWithSigners, signAndSendTransactionWithSigners, signTransactionWithSigners }; | ||
//# sourceMappingURL=out.js.map | ||
//# sourceMappingURL=index.node.js.map |
@@ -5,27 +5,37 @@ 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 o=r.length-t;if(o<n)throw new Error(`Codec [${e}] expected ${n} bytes, got ${o}.`)}var b=e=>{let n=e.filter(i=>i.length);if(n.length===0)return e.length?e[0]:new Uint8Array;if(n.length===1)return n[0];let r=n.reduce((i,s)=>i+s.length,0),t=new Uint8Array(r),o=0;return n.forEach(i=>{t.set(i,o),o+=i.length;}),t},Te=(e,n)=>{if(e.length>=n)return e;let r=new Uint8Array(n).fill(0);return r.set(e),r},R=(e,n)=>Te(e.length<=n?e:e.slice(0,n),n);function re(e,n,r){return {description:r!=null?r:`fixed(${n}, ${e.description})`,fixedSize:n,maxSize:n}}function C(e,n,r){return {...re(e,n,r),encode:t=>R(e.encode(t),n)}}function O(e,n,r){return {...re(e,n,r),decode:(t,o=0)=>{x("fixCodec",n,t,o),(o>0||t.length>n)&&(t=t.slice(o,o+n)),e.fixedSize!==null&&(t=R(t,e.fixedSize));let[i]=e.decode(t,0);return [i,o+n]}}}function z(e,n){return {description:e.description,encode:r=>e.encode(n(r)),fixedSize:e.fixedSize,maxSize:e.maxSize}}function te(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 oe(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 ie(e){let n=oe(e);return {description:n.description,encode(r){e.range&&te(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 Ee(e){let n=oe(e);return {decode(r,t=0){w(n.description,r,t),x(n.description,e.size,r,t);let o=new DataView(ve(r,t,e.size));return [e.get(o,n.littleEndian),t+e.size]},description:n.description,fixedSize:n.fixedSize,maxSize:n.maxSize}}function ve(e,n,r){let t=e.byteOffset+(n!=null?n:0),o=r!=null?r:e.byteLength;return e.buffer.slice(t,t+o)}var p=(e={})=>{var n;return {description:(n=e.description)!=null?n:"shortU16",encode:r=>{te("shortU16",0,65535,r);let t=[0];for(let o=0;;o+=1){let i=r>>o*7;if(i===0)break;let s=127&i;t[o]=s,o>0&&(t[o-1]|=128);}return new Uint8Array(t)},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={})=>Ee({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 Ie(e,n,r=n){if(!n.match(new RegExp(`^[${e}]*$`)))throw new Error(`Expected a string of base ${e.length}, got [${r}].`)}var De=e=>{let n=e.length,r=BigInt(n);return {description:`base${n}`,encode(t){if(Ie(e,t),t==="")return new Uint8Array;let o=[...t],i=o.findIndex(m=>m!==e[0]);i=i===-1?o.length:i;let s=Array(i).fill(0);if(i===o.length)return Uint8Array.from(s);let a=o.slice(i),d=0n,c=1n;for(let m=a.length-1;m>=0;m-=1)d+=c*BigInt(e.indexOf(a[m])),c*=r;let f=[];for(;d>0n;)f.unshift(Number(d%256n)),d/=256n;return Uint8Array.from(s.concat(f))},fixedSize:null,maxSize:null}},Ce=e=>{let n=e.length,r=BigInt(n);return {decode(t,o=0){let i=o===0?t:t.slice(o);if(i.length===0)return ["",0];let s=i.findIndex(f=>f!==0);s=s===-1?i.length:s;let a=e[0].repeat(s);if(s===i.length)return [a,t.length];let d=i.slice(s).reduce((f,m)=>f*256n+BigInt(m),0n),c=[];for(;d>0n;)c.unshift(e[Number(d%r)]),d/=r;return [a+c.join(""),t.length]},description:`base${n}`,fixedSize:null,maxSize:null}};var se="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",M=()=>De(se),_=()=>Ce(se);var Be=e=>e.replace(/\u0000/g,"");var ke=globalThis.TextDecoder,Me=globalThis.TextEncoder,$e=()=>{let e;return {description:"utf8",encode:n=>new Uint8Array((e||(e=new Me)).encode(n)),fixedSize:null,maxSize:null}},Ue=()=>{let e;return {decode(n,r=0){let t=(e||(e=new ke)).decode(n.slice(r));return [Be(t),n.length]},description:"utf8",fixedSize:null,maxSize:null}};var $=(e={})=>{var o,i,s;let n=(o=e.size)!=null?o:k(),r=(i=e.encoding)!=null?i:$e(),t=(s=e.description)!=null?s:`string(${r.description}; ${ae(n)})`;return n==="variable"?{...r,description:t}:typeof n=="number"?C(r,n,t):{description:t,encode:a=>{let d=r.encode(a),c=n.encode(d.length);return b([c,d])},fixedSize:null,maxSize:null}},F=(e={})=>{var o,i,s;let n=(o=e.size)!=null?o:L(),r=(i=e.encoding)!=null?i:Ue(),t=(s=e.description)!=null?s:`string(${r.description}; ${ae(n)})`;return n==="variable"?{...r,description:t}:typeof n=="number"?O(r,n,t):{decode:(a,d=0)=>{w("string",a,d);let[c,f]=n.decode(a,d),m=Number(c);d=f;let ne=a.slice(d,d+m);x("string",m,ne);let[we,ze]=r.decode(ne);return d+=ze,[we,d]},description:t,fixedSize:null,maxSize:null}};function ae(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 Pe(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 de(){var e;if(K(),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 Pe(globalThis.crypto.subtle))throw new Error(`This runtime does not support the generation of Ed25519 key pairs. | ||
function T(e){let n={};return e.forEach(r=>{if(!n[r.address])n[r.address]=r;else if(n[r.address]!==r)throw new Error(`Multiple distinct signers were identified for address "${r.address}". Please ensure that you are using the same signer instance for each address.`)}),Object.values(n)}function Me(e){var n;return T(((n=e.accounts)!=null?n:[]).flatMap(r=>"signer"in r?r.signer:[]))}function v(e){return T(e.instructions.flatMap(Me))}function oe(e){return e>=2}function ke(e,n){if(!n.accounts||n.accounts.length===0)return n;let r=new Map(T(e).map(t=>[t.address,t]));return Object.freeze({...n,accounts:n.accounts.map(t=>{let i=r.get(t.address);return !oe(t.role)||"signer"in t||!i?t:Object.freeze({...t,signer:i})})})}function tr(e,n){return n.instructions.length===0?n:Object.freeze({...n,instructions:n.instructions.map(r=>ke(e,r))})}function C(e,n,r=0){if(n.length-r<=0)throw new Error(`Codec [${e}] cannot decode empty byte arrays.`)}function w(e,n,r,t=0){let i=r.length-t;if(i<n)throw new Error(`Codec [${e}] expected ${n} bytes, got ${i}.`)}var z=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},Pe=(e,n)=>{if(e.length>=n)return e;let r=new Uint8Array(n).fill(0);return r.set(e),r},F=(e,n)=>Pe(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 P(e,n,r){return {...se(e,n,r),encode:t=>F(e.encode(t),n)}}function j(e,n,r){return {...se(e,n,r),decode:(t,i=0)=>{w("fixCodec",n,t,i),(i>0||t.length>n)&&(t=t.slice(i,i+n)),e.fixedSize!==null&&(t=F(t,e.fixedSize));let[o]=e.decode(t,0);return [o,i+n]}}}function B(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 Ne(e){let n=ce(e);return {decode(r,t=0){C(n.description,r,t),w(n.description,e.size,r,t);let i=new DataView(Re(r,t,e.size));return [e.get(i,n.littleEndian),t+e.size]},description:n.description,fixedSize:n.fixedSize,maxSize:n.maxSize}}function Re(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 h=(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 R=(e={})=>de({config:e,name:"u32",range:[0,+"0xffffffff"],set:(n,r,t)=>n.setUint32(0,r,t),size:4}),K=(e={})=>Ne({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(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),c=0n,d=1n;for(let p=a.length-1;p>=0;p-=1)c+=d*BigInt(e.indexOf(a[p])),d*=r;let g=[];for(;c>0n;)g.unshift(Number(c%256n)),c/=256n;return Uint8Array.from(s.concat(g))},fixedSize:null,maxSize:null}},Oe=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(g=>g!==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((g,p)=>g*256n+BigInt(p),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",$=()=>Ue(ue),V=()=>Oe(ue);var We=e=>e.replace(/\u0000/g,"");var Le=globalThis.TextDecoder,_e=globalThis.TextEncoder,Fe=()=>{let e;return {description:"utf8",encode:n=>new Uint8Array((e||(e=new _e)).encode(n)),fixedSize:null,maxSize:null}},je=()=>{let e;return {decode(n,r=0){let t=(e||(e=new Le)).decode(n.slice(r));return [We(t),n.length]},description:"utf8",fixedSize:null,maxSize:null}};var U=(e={})=>{var i,o,s;let n=(i=e.size)!=null?i:R(),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"?P(r,n,t):{description:t,encode:a=>{let c=r.encode(a),d=n.encode(c.length);return z([d,c])},fixedSize:null,maxSize:null}},G=(e={})=>{var i,o,s;let n=(i=e.size)!=null?i:K(),r=(o=e.encoding)!=null?o:je(),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)=>{C("string",a,c);let[d,g]=n.decode(a,c),p=Number(d);c=g;let ie=a.slice(c,c+p);w("string",p,ie);let[Be,De]=r.decode(ie);return c+=De,[Be,c]},description:t,fixedSize:null,maxSize:null}};function ge(e){return typeof e=="object"?e.description:`${e}`}function H(){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 x;async function Ke(e){return x===void 0&&(x=new Promise(n=>{e.generateKey("Ed25519",!1,["sign","verify"]).catch(()=>{n(x=!1);}).then(()=>{n(x=!0);});})),typeof x=="boolean"?x:await x}async function fe(){var e;if(H(),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 Ke(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 ce(){var e;if(K(),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 ue(){var e;if(K(),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 j,V;function H(){return j||(j=M()),j}function Ne(){return V||(V=_()),V}function fe(e){return !(e.length<32||e.length>44||H().encode(e).byteLength!==32)}function le(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 Re(e){return le(e),e}function W(e){var n;return z($({description:(n=e==null?void 0:e.description)!=null?n:"Address",encoding:H(),size:32}),r=>Re(r))}function ge(e){var n;return F({description:(n=e==null?void 0:e.description)!=null?n:"Address",encoding:Ne(),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 ce(),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]=ge().decode(new Uint8Array(n));return r}async function me(){return await de(),await crypto.subtle.generateKey("Ed25519",!1,["sign","verify"])}async function N(e,n){await ue();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 Le(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 _e(e,n){return typeof e=="object"?e.encode(n):new Uint8Array}function Fe(e,n,r){if(n!==r)throw new Error(`Expected [${e}] to have ${n} items, got ${r}.`)}function Ke(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}; ${Le(n)})`,fixedSize:pe(n,[e.fixedSize]),maxSize:pe(n,[e.maxSize])}}function y(e,n={}){var t;let r=(t=n.size)!=null?t:k();return {...Ke(e,r,n.description),encode:o=>(typeof r=="number"&&Fe("array",r,o.length),b([_e(r,o.length),...o.map(i=>e.encode(i))]))}}function he(e={}){var i,s;let n=(i=e.size)!=null?i:"variable",r=typeof n=="object"?n.description:`${n}`,t=(s=e.description)!=null?s:`bytes(${r})`,o={description:t,encode:a=>a,fixedSize:null,maxSize:null};return n==="variable"?o:typeof n=="number"?C(o,n,t):{...o,encode:a=>{let d=o.encode(a),c=n.encode(d.length);return b([c,d])}}}function je(e,n){let r=e.map(([t,o])=>`${String(t)}: ${o.description}`).join(", ");return {description:n!=null?n:`struct(${r})`,fixedSize:G(e.map(([,t])=>t.fixedSize)),maxSize:G(e.map(([,t])=>t.maxSize))}}function A(e,n={}){return {...je(e,n.description),encode:r=>{let t=e.map(([o,i])=>i.encode(r[o]));return b(t)}}}var T=(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))(T||{}),Ve=1;function E(e){return e>=2}function v(e){return (e&Ve)!==0}function Se(e,n){return e|n}function ye(e,n,r){var t;e[n]=r((t=e[n])!=null?t:{role:T.READONLY});}var u=Symbol("AddressMapTypeProperty");function He(e,n){let r={[e]:{[u]:0,role:T.WRITABLE_SIGNER}},t=new Set;for(let o of n){ye(r,o.programAddress,s=>{if(t.add(o.programAddress),u in s){if(v(s.role))switch(s[u]){case 0:throw new Error(`This transaction includes an address (\`${o.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 (\`${o.programAddress}\`) which is both invoked and marked writable. Program addresses may not be writable.`)}if(s[u]===2)return s}return {[u]:2,role:T.READONLY}});let i;if(o.accounts)for(let s of o.accounts)ye(r,s.address,a=>{let{address:d,...c}=s;if(u in a)switch(a[u]){case 0:return a;case 1:{let f=Se(a.role,c.role);if("lookupTableAddress"in c){if(a.lookupTableAddress!==c.lookupTableAddress&&(i||(i=U()))(c.lookupTableAddress,a.lookupTableAddress)<0)return {[u]:1,...c,role:f}}else if(E(c.role))return {[u]:2,role:f};return a.role!==f?{...a,role:f}:a}case 2:{let f=Se(a.role,c.role);if(t.has(s.address)){if(v(c.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!==f?{...a,role:f}:a}else return "lookupTableAddress"in c&&!E(a.role)?{...c,[u]:1,role:f}:a.role!==f?{...a,role:f}:a}}return "lookupTableAddress"in c?{...c,[u]:1}:{...c,[u]:2}});}return r}function We(e){let n;return Object.entries(e).sort(([t,o],[i,s])=>{if(o[u]!==s[u]){if(o[u]===0)return -1;if(s[u]===0)return 1;if(o[u]===2)return -1;if(s[u]===2)return 1}let a=E(o.role);if(a!==E(s.role))return a?-1:1;let d=v(o.role);return d!==v(s.role)?d?-1:1:(n||(n=U()),o[u]===1&&s[u]===1&&o.lookupTableAddress!==s.lookupTableAddress?n(o.lookupTableAddress,s.lookupTableAddress):n(t,i))}).map(([t,o])=>({address:t,...o}))}function Ge(e){var r;let n={};for(let t of e){if(!("lookupTableAddress"in t))continue;let o=n[r=t.lookupTableAddress]||(n[r]={readableIndices:[],writableIndices:[]});t.role===T.WRITABLE?o.writableIndices.push(t.addressIndex):o.readableIndices.push(t.addressIndex);}return Object.keys(n).sort(U()).map(t=>({lookupTableAddress:t,...n[t]}))}function Ye(e){let n=0,r=0,t=0;for(let o of e){if("lookupTableAddress"in o)break;let i=v(o.role);E(o.role)?(t++,i||r++):i||n++;}return {numReadonlyNonSignerAccounts:n,numReadonlySignerAccounts:r,numSignerAccounts:t}}function Xe(e){let n={};for(let[r,t]of e.entries())n[t.address]=r;return n}function qe(e,n){let r=Xe(n);return e.map(({accounts:t,data:o,programAddress:i})=>({programAddressIndex:r[i],...t?{accountIndices:t.map(({address:s})=>r[s])}:null,...o?{data:o}:null}))}function Ze(e){return "nonce"in e?e.nonce:e.blockhash}function Je(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=He(e.feePayer,e.instructions),r=We(n);return {...e.version!=="legacy"?{addressTableLookups:Ge(r)}:null,header:Ye(r),instructions:qe(e.instructions,r),lifetimeToken:Ze(e.lifetimeConstraint),staticAccounts:Je(r),version:e.version}}var en="lookupTableAddress",nn="writableIndices",rn="readableIndices",tn="addressTableLookup",Y;function on(){return Y||(Y=A([["lookupTableAddress",W({description:en})],["writableIndices",y(h(),{description:nn,size:p()})],["readableIndices",y(h(),{description:rn,size:p()})]],{description:tn})),Y}var X;function sn(){return X||(X=h()),X}function q(e){let n=sn();return {...n,description:e!=null?e:n.description}}var an=void 0,dn=void 0,cn=void 0,un=void 0;function fn(){return A([["numSignerAccounts",q(an)],["numReadonlySignerAccounts",q(dn)],["numReadonlyNonSignerAccounts",q(cn)]],{description:un})}var ln="programAddressIndex",gn=void 0,mn="accountIndices",pn="data",Z;function hn(){return Z||(Z=z(A([["programAddressIndex",h({description:ln})],["accountIndices",y(h({description:gn}),{description:mn,size:p()})],["data",he({description:pn,size:p()})]]),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)}})),Z}var Sn=128,yn={description:"",fixedSize:null,maxSize:1};function xn(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|Sn])}function bn(){return {...yn,encode:xn}}var An="staticAccounts",wn="lifetimeToken",zn="instructions",Tn="addressTableLookups";function En(){return A(xe())}function vn(){return z(A([...xe(),["addressTableLookups",In()]]),e=>{var n;return e.version==="legacy"?e:{...e,addressTableLookups:(n=e.addressTableLookups)!=null?n:[]}})}function xe(){return [["version",bn()],["header",fn()],["staticAccounts",y(W(),{description:An,size:p()})],["lifetimeToken",$({description:wn,encoding:M(),size:32})],["instructions",y(hn(),{description:zn,size:p()})]]}function In(){return y(on(),{description:Tn,size:p()})}var Dn="message";function Cn(){return {description:Dn,encode:e=>e.version==="legacy"?En().encode(e):vn().encode(e),fixedSize:null,maxSize:null}}async function be(e,n){let r=Qe(n),t="signatures"in n?{...n.signatures}:{},o=Cn().encode(r),i=await Promise.all(e.map(a=>Promise.all([P(a.publicKey),N(a.privateKey,o)])));for(let[a,d]of i)t[a]=d;let s={...n,signatures:t};return Object.freeze(s),s}function I(e){return "signMessages"in e&&typeof e.signMessages=="function"}function Ar(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 Tr(e){if(!D(e))throw new Error("The provided value does not implement the TransactionPartialSigner interface")}function Bn(e){return "keyPair"in e&&typeof e.keyPair=="object"&&I(e)&&D(e)}function Pr(e){if(!Bn(e))throw new Error("The provided value does not implement the KeyPairSigner interface")}async function kn(e){let n=await P(e.publicKey);return Object.freeze({address:n,keyPair:e,signMessages:t=>Promise.all(t.map(async o=>Object.freeze({[n]:await N(e.privateKey,o.content)}))),signTransactions:t=>Promise.all(t.map(async o=>{let i=await be([e],o);return Object.freeze({[n]:i.signatures[n]})}))})}async function Nr(){return kn(await me())}function J(e){return fe(e.address)&&"modifyAndSignMessages"in e&&typeof e.modifyAndSignMessages=="function"}function Fr(e){if(!J(e))throw new Error("The provided value does not implement the MessageModifyingSigner interface")}function Mn(e){return I(e)||J(e)}function Yr(e){if(!Mn(e))throw new Error("The provided value does not implement any of the MessageSigner interfaces")}var Ae=globalThis.TextEncoder;function nt(e,n={}){return Object.freeze({content:typeof e=="string"?new Ae().encode(e):e,signatures:Object.freeze({...n})})}function Q(e){return "modifyAndSignTransactions"in e&&typeof e.modifyAndSignTransactions=="function"}function ot(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 at(e){if(!ee(e))throw new Error("The provided value does not implement the TransactionSendingSigner interface")}function $n(e){return D(e)||Q(e)||ee(e)}function ht(e){if(!$n(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(H(),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(H(),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=$()),Y}function Ve(){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 Ge(e){return Se(e),e}function Z(e){var n;return B(U({description:(n=e==null?void 0:e.description)!=null?n:"Address",encoding:q(),size:32}),r=>Ge(r))}function Te(e){var n;return G({description:(n=e==null?void 0:e.description)!=null?n:"Address",encoding:Ve(),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 W(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]=Te().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 Ye(e){return typeof e=="object"?e.description:`${e}`}function ye(e,n){if(typeof e!="number")return null;if(e===0)return 0;let r=J(n);return r===null?null:r*e}function Xe(e,n){return typeof e=="object"?e.encode(n):new Uint8Array}function qe(e,n,r){if(n!==r)throw new Error(`Expected [${e}] to have ${n} items, got ${r}.`)}function Ze(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}; ${Ye(n)})`,fixedSize:ye(n,[e.fixedSize]),maxSize:ye(n,[e.maxSize])}}function A(e,n={}){var t;let r=(t=n.size)!=null?t:R();return {...Ze(e,r,n.description),encode:i=>(typeof r=="number"&&qe("array",r,i.length),z([Xe(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"?P(i,n,t):{...i,encode:a=>{let c=i.encode(a),d=n.encode(c.length);return z([d,c])}}}function Je(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 E(e,n={}){return {...Je(e,n.description),encode:r=>{let t=e.map(([i,o])=>o.encode(r[i]));return z(t)}}}var D=(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))(D||{}),Qe=1;function I(e){return e>=2}function M(e){return (e&Qe)!==0}function Ae(e,n){return e|n}function be(e,n,r){var t;e[n]=r((t=e[n])!=null?t:{role:D.READONLY});}var f=Symbol("AddressMapTypeProperty");function en(e,n){let r={[e]:{[f]:0,role:D.WRITABLE_SIGNER}},t=new Set;for(let i of n){be(r,i.programAddress,s=>{if(t.add(i.programAddress),f in s){if(M(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:D.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 g=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:g}}else if(I(d.role))return {[f]:2,role:g};return a.role!==g?{...a,role:g}:a}case 2:{let g=Ae(a.role,d.role);if(t.has(s.address)){if(M(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!==g?{...a,role:g}:a}else return "lookupTableAddress"in d&&!I(a.role)?{...d,[f]:1,role:g}:a.role!==g?{...a,role:g}:a}}return "lookupTableAddress"in d?{...d,[f]:1}:{...d,[f]:2}});}return r}function nn(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=I(i.role);if(a!==I(s.role))return a?-1:1;let c=M(i.role);return c!==M(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 rn(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===D.WRITABLE?i.writableIndices.push(t.addressIndex):i.readableIndices.push(t.addressIndex);}return Object.keys(n).sort(O()).map(t=>({lookupTableAddress:t,...n[t]}))}function tn(e){let n=0,r=0,t=0;for(let i of e){if("lookupTableAddress"in i)break;let o=M(i.role);I(i.role)?(t++,o||r++):o||n++;}return {numReadonlyNonSignerAccounts:n,numReadonlySignerAccounts:r,numSignerAccounts:t}}function on(e){let n={};for(let[r,t]of e.entries())n[t.address]=r;return n}function sn(e,n){let r=on(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 an(e){return "nonce"in e?e.nonce:e.blockhash}function cn(e){let n=e.findIndex(t=>"lookupTableAddress"in t);return (n===-1?e:e.slice(0,n)).map(({address:t})=>t)}function dn(e){let n=en(e.feePayer,e.instructions),r=nn(n);return {...e.version!=="legacy"?{addressTableLookups:rn(r)}:null,header:tn(r),instructions:sn(e.instructions,r),lifetimeToken:an(e.lifetimeConstraint),staticAccounts:cn(r),version:e.version}}var un="lookupTableAddress",gn="writableIndices",fn="readableIndices",ln="addressTableLookup",Q;function mn(){return Q||(Q=E([["lookupTableAddress",Z({description:un})],["writableIndices",A(y(),{description:gn,size:h()})],["readableIndices",A(y(),{description:fn,size:h()})]],{description:ln})),Q}var ee;function pn(){return ee||(ee=y()),ee}function ne(e){let n=pn();return {...n,description:e!=null?e:n.description}}var Sn=void 0,Tn=void 0,hn=void 0,yn=void 0;function xn(){return E([["numSignerAccounts",ne(Sn)],["numReadonlySignerAccounts",ne(Tn)],["numReadonlyNonSignerAccounts",ne(hn)]],{description:yn})}var An="programAddressIndex",bn=void 0,wn="accountIndices",zn="data",re;function En(){return re||(re=B(E([["programAddressIndex",y({description:An})],["accountIndices",A(y({description:bn}),{description:wn,size:h()})],["data",xe({description:zn,size:h()})]]),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 In=128,vn={description:"",fixedSize:null,maxSize:1};function Cn(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|In])}function Bn(){return {...vn,encode:Cn}}var Dn="staticAccounts",Mn="lifetimeToken",kn="instructions",Pn="addressTableLookups";function Nn(){return E(we())}function Rn(){return B(E([...we(),["addressTableLookups",$n()]]),e=>{var n;return e.version==="legacy"?e:{...e,addressTableLookups:(n=e.addressTableLookups)!=null?n:[]}})}function we(){return [["version",Bn()],["header",xn()],["staticAccounts",A(Z(),{description:Dn,size:h()})],["lifetimeToken",U({description:Mn,encoding:$(),size:32})],["instructions",A(En(),{description:kn,size:h()})]]}function $n(){return A(mn(),{description:Pn,size:h()})}var Un="message";function On(){return {description:Un,encode:e=>e.version==="legacy"?Nn().encode(e):Rn().encode(e),fixedSize:null,maxSize:null}}async function ze(e,n){let r=dn(n),t="signatures"in n?{...n.signatures}:{},i=On().encode(r),o=await Promise.all(e.map(a=>Promise.all([W(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 Ee(e){let n=e.instructions.flatMap(t=>{var i,o;return (o=(i=t.accounts)==null?void 0:i.filter(s=>I(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 k(e){return "signMessages"in e&&typeof e.signMessages=="function"}function Gr(e){if(!k(e))throw new Error("The provided value does not implement the MessagePartialSigner interface")}function m(e){return "signTransactions"in e&&typeof e.signTransactions=="function"}function Xr(e){if(!m(e))throw new Error("The provided value does not implement the TransactionPartialSigner interface")}function Wn(e){return "keyPair"in e&&typeof e.keyPair=="object"&&k(e)&&m(e)}function st(e){if(!Wn(e))throw new Error("The provided value does not implement the KeyPairSigner interface")}async function Ln(e){let n=await W(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 at(){return Ln(await he())}function te(e){return pe(e.address)&&"modifyAndSignMessages"in e&&typeof e.modifyAndSignMessages=="function"}function ft(e){if(!te(e))throw new Error("The provided value does not implement the MessageModifyingSigner interface")}function _n(e){return k(e)||te(e)}function yt(e){if(!_n(e))throw new Error("The provided value does not implement any of the MessageSigner interfaces")}function bt(e){return Object.freeze({address:e,signMessages:async r=>r.map(()=>Object.freeze({})),signTransactions:async r=>r.map(()=>Object.freeze({}))})}function S(e){return "modifyAndSignTransactions"in e&&typeof e.modifyAndSignTransactions=="function"}function Et(e){if(!S(e))throw new Error("The provided value does not implement the TransactionModifyingSigner interface")}function b(e){return "signAndSendTransactions"in e&&typeof e.signAndSendTransactions=="function"}function Ct(e){if(!b(e))throw new Error("The provided value does not implement the TransactionSendingSigner interface")}function _(e){return m(e)||S(e)||b(e)}function Ut(e){if(!_(e))throw new Error("The provided value does not implement any of the TransactionSigner interfaces")}async function Fn(e,n={}){let{partialSigners:r,modifyingSigners:t}=Ie(T(v(e).filter(_)),{identifySendingSigner:!1});return ve(e,t,r,n.abortSignal)}async function ni(e,n={}){let r=await Fn(e,n);return Ee(r),r}async function ri(e,n={}){let r=n.abortSignal,{partialSigners:t,modifyingSigners:i,sendingSigner:o}=Ie(T(v(e).filter(_)));r==null||r.throwIfAborted();let s=await ve(e,i,t,r);if(!o)throw new Error("No `TransactionSendingSigner` was identified. Please provide a valid `ITransactionWithSingleSendingSigner` transaction.");r==null||r.throwIfAborted();let[a]=await o.signAndSendTransactions([s],{abortSignal:r});return r==null||r.throwIfAborted(),a}function Ie(e,n={}){var a;let t=((a=n.identifySendingSigner)!=null?a:!0)?jn(e):null,i=e.filter(c=>c!==t&&(S(c)||m(c))),o=Kn(i),s=i.filter(m).filter(c=>!o.includes(c));return Object.freeze({modifyingSigners:o,partialSigners:s,sendingSigner:t})}function jn(e){let n=e.filter(b);if(n.length===0)return null;let r=n.filter(t=>!S(t)&&!m(t));return r.length>0?r[0]:n[0]}function Kn(e){let n=e.filter(S);if(n.length===0)return [];let r=n.filter(t=>!m(t));return r.length>0?r:[n[0]]}async function ve(e,n=[],r=[],t){var a;let i=await n.reduce(async(c,d)=>{t==null||t.throwIfAborted();let[g]=await d.modifyAndSignTransactions([await c],{abortSignal:t});return Object.freeze(g)},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 Ce=globalThis.TextEncoder;function di(e,n={}){return Object.freeze({content:typeof e=="string"?new Ce().encode(e):e,signatures:Object.freeze({...n})})}function Ti(e){try{return Vn(e),!0}catch{return !1}}function Vn(e){let r=v(e).filter(b);if(r.length===0){let i=new Error("No `TransactionSendingSigner` was identified.");throw i.name="MissingTransactionSendingSignerError",i}if(r.filter(i=>!m(i)&&!S(i)).length>1){let i=new Error("More than one `TransactionSendingSigner` was identified.");throw i.name="MultipleTransactionSendingSignersError",i}} | ||
exports.assertIsKeyPairSigner = Pr; | ||
exports.assertIsMessageModifyingSigner = Fr; | ||
exports.assertIsMessagePartialSigner = Ar; | ||
exports.assertIsMessageSigner = Yr; | ||
exports.assertIsTransactionModifyingSigner = ot; | ||
exports.assertIsTransactionPartialSigner = Tr; | ||
exports.assertIsTransactionSendingSigner = at; | ||
exports.assertIsTransactionSigner = ht; | ||
exports.createSignableMessage = nt; | ||
exports.createSignerFromKeyPair = kn; | ||
exports.generateKeyPairSigner = Nr; | ||
exports.isKeyPairSigner = Bn; | ||
exports.isMessageModifyingSigner = J; | ||
exports.isMessagePartialSigner = I; | ||
exports.isMessageSigner = Mn; | ||
exports.isTransactionModifyingSigner = Q; | ||
exports.isTransactionPartialSigner = D; | ||
exports.isTransactionSendingSigner = ee; | ||
exports.isTransactionSigner = $n; | ||
exports.addSignersToInstruction = ke; | ||
exports.addSignersToTransaction = tr; | ||
exports.assertIsKeyPairSigner = st; | ||
exports.assertIsMessageModifyingSigner = ft; | ||
exports.assertIsMessagePartialSigner = Gr; | ||
exports.assertIsMessageSigner = yt; | ||
exports.assertIsTransactionModifyingSigner = Et; | ||
exports.assertIsTransactionPartialSigner = Xr; | ||
exports.assertIsTransactionSendingSigner = Ct; | ||
exports.assertIsTransactionSigner = Ut; | ||
exports.assertIsTransactionWithSingleSendingSigner = Vn; | ||
exports.createNoopSigner = bt; | ||
exports.createSignableMessage = di; | ||
exports.createSignerFromKeyPair = Ln; | ||
exports.generateKeyPairSigner = at; | ||
exports.getSignersFromInstruction = Me; | ||
exports.getSignersFromTransaction = v; | ||
exports.isKeyPairSigner = Wn; | ||
exports.isMessageModifyingSigner = te; | ||
exports.isMessagePartialSigner = k; | ||
exports.isMessageSigner = _n; | ||
exports.isTransactionModifyingSigner = S; | ||
exports.isTransactionPartialSigner = m; | ||
exports.isTransactionSendingSigner = b; | ||
exports.isTransactionSigner = _; | ||
exports.isTransactionWithSingleSendingSigner = Ti; | ||
exports.partiallySignTransactionWithSigners = Fn; | ||
exports.signAndSendTransactionWithSigners = ri; | ||
exports.signTransactionWithSigners = ni; | ||
@@ -32,0 +42,0 @@ return exports; |
@@ -0,1 +1,3 @@ | ||
export * from './account-signer-meta'; | ||
export * from './add-signers'; | ||
export * from './keypair-signer'; | ||
@@ -5,2 +7,4 @@ export * from './message-modifying-signer'; | ||
export * from './message-signer'; | ||
export * from './noop-signer'; | ||
export * from './sign-transaction'; | ||
export * from './signable-message'; | ||
@@ -11,3 +15,4 @@ export * from './transaction-modifying-signer'; | ||
export * from './transaction-signer'; | ||
export * from './transaction-with-single-sending-signer'; | ||
export * from './types'; | ||
//# sourceMappingURL=index.d.ts.map |
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.699bde0", | ||
"version": "2.0.0-experimental.819422a", | ||
"description": "An abstraction layer over signing messages and transactions in Solana", | ||
@@ -52,5 +52,6 @@ "exports": { | ||
"dependencies": { | ||
"@solana/addresses": "2.0.0-experimental.699bde0", | ||
"@solana/keys": "2.0.0-experimental.699bde0", | ||
"@solana/transactions": "2.0.0-experimental.699bde0" | ||
"@solana/addresses": "2.0.0-experimental.819422a", | ||
"@solana/instructions": "2.0.0-experimental.819422a", | ||
"@solana/keys": "2.0.0-experimental.819422a", | ||
"@solana/transactions": "2.0.0-experimental.819422a" | ||
}, | ||
@@ -57,0 +58,0 @@ "devDependencies": { |
226
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,198 @@ | ||
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` | ||
Composable type that allows `IAccountSignerMetas` to be used inside the instruction's `accounts` array. | ||
```ts | ||
const myInstructionWithSigners: IInstruction & IInstructionWithSigners = { | ||
programAddress: address('1234..5678'), | ||
accounts: [ | ||
{ | ||
address: myTransactionSigner.address, | ||
role: AccountRole.READONLY_SIGNER, | ||
signer: myTransactionSigner, | ||
}, | ||
], | ||
}; | ||
``` | ||
#### `ITransactionWithSigners` | ||
Composable type that allows `IAccountSignerMetas` to be used inside all of the transaction's account metas. | ||
```ts | ||
const myTransactionWithSigners: BaseTransaction & ITransactionWithSigners = { | ||
instructions: [ | ||
myInstructionA as IInstruction & IInstructionWithSigners, | ||
myInstructionB as IInstruction & IInstructionWithSigners, | ||
myInstructionC as IInstruction, | ||
], | ||
version: 0, | ||
}; | ||
``` | ||
### 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); | ||
``` | ||
#### `addSignersToInstruction()` | ||
Helper function that adds the provided signers to any of the applicable account metas. For an account meta to match a provided signer it: | ||
- Must have a signer role (`AccountRole.READONLY_SIGNER` or `AccountRole.WRITABLE_SIGNER`). | ||
- Must have the same address as the provided signer. | ||
- Must not have an attached signer already. | ||
```ts | ||
const myInstruction: IInstruction = { | ||
accounts: [ | ||
{ address: '1111' as Address, role: AccountRole.READONLY_SIGNER }, | ||
{ address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER }, | ||
], | ||
// ... | ||
}; | ||
const signerA: TransactionSigner<'1111'>; | ||
const signerB: TransactionSigner<'2222'>; | ||
const myInstructionWithSigners = addSignersToInstruction([mySignerA, mySignerB], myInstruction); | ||
// myInstructionWithSigners.accounts[0].signer === mySignerA | ||
// myInstructionWithSigners.accounts[1].signer === mySignerB | ||
``` | ||
#### `addSignersToTransaction()` | ||
Similarly to `addSignersToInstruction`, this function adds signer to all the applicable account metas of all the instructions inside a transaction. | ||
```ts | ||
const myTransactionWithSigners = addSignersToTransaction(mySigners, myTransaction); | ||
``` | ||
## 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 = await partiallySignTransactionWithSigners(myTransaction); | ||
``` | ||
It also accepts an optional `AbortSignal` that will be propagated to all signers. | ||
```ts | ||
const mySignedTransaction = await partiallySignTransactionWithSigners(myTransaction, { | ||
abortSignal: myAbortController.signal, | ||
}); | ||
``` | ||
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 = await signTransactionWithSigners(myTransaction); | ||
// With additional config. | ||
const mySignedTransaction = await signTransactionWithSigners(myTransaction, { | ||
abortSignal: myAbortController.signal, | ||
}); | ||
// 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 = await signAndSendTransactionWithSigners(myTransaction); | ||
// With additional config. | ||
const myTransactionSignature = await signAndSendTransactionWithSigners(myTransaction, { | ||
abortSignal: myAbortController.signal, | ||
}); | ||
``` | ||
Similarly to the `partiallySignTransactionWithSigners` function, it first uses all `TransactionModifyingSigners` sequentially before using all `TransactionPartialSigners` in parallel. It then sends the transaction using the `TransactionSendingSigner` it identified. | ||
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` exists. | ||
- `TransactionModifyingSigner`, if no other `TransactionModifyingSigner` exists. | ||
- `TransactionPartialSigner`, otherwise. | ||
The provided transaction must be of type `ITransactionWithSingleSendingSigner` meaning that it must contain exactly one `TransactionSendingSigner` inside its account metas. If more than one composite signers implement the `TransactionSendingSigner` interface, one of them will be selected as the sending signer. | ||
Therefore, you may use the `assertIsTransactionWithSingleSendingSigner()` function to ensure the transaction is of the expected type. | ||
```ts | ||
assertIsTransactionWithSingleSendingSigner(myTransaction); | ||
const myTransactionSignature = await signAndSendTransactionWithSigners(myTransaction); | ||
``` | ||
Alternatively, you may use the `isTransactionWithSingleSendingSigner()` function to provide a fallback in case the transaction does not contain any sending signer. | ||
```ts | ||
let transactionSignature: SignatureBytes; | ||
if (isTransactionWithSingleSendingSigner(transaction)) { | ||
transactionSignature = await signAndSendTransactionWithSigners(transaction); | ||
} else { | ||
const signedTransaction = await signTransactionWithSigners(transaction); | ||
const encodedTransaction = getBase64EncodedWireTransaction(signedTransaction); | ||
transactionSignature = await rpc.sendTransaction(encodedTransaction).send(); | ||
} | ||
``` |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
600468
51
3535
571
4
+ Added@solana/addresses@2.0.0-experimental.819422a(transitive)
+ Added@solana/assertions@2.0.0-experimental.819422a(transitive)
+ Added@solana/codecs-core@2.0.0-experimental.819422a(transitive)
+ Added@solana/codecs-data-structures@2.0.0-experimental.819422a(transitive)
+ Added@solana/codecs-numbers@2.0.0-experimental.819422a(transitive)
+ Added@solana/codecs-strings@2.0.0-experimental.819422a(transitive)
+ Added@solana/functional@2.0.0-experimental.819422a(transitive)
+ Added@solana/instructions@2.0.0-experimental.819422a(transitive)
+ Added@solana/keys@2.0.0-experimental.819422a(transitive)
+ Added@solana/transactions@2.0.0-experimental.819422a(transitive)
- Removed@solana/addresses@2.0.0-experimental.699bde0(transitive)
- Removed@solana/assertions@2.0.0-experimental.699bde0(transitive)
- Removed@solana/codecs-core@2.0.0-experimental.699bde0(transitive)
- Removed@solana/codecs-data-structures@2.0.0-experimental.699bde0(transitive)
- Removed@solana/codecs-numbers@2.0.0-experimental.699bde0(transitive)
- Removed@solana/codecs-strings@2.0.0-experimental.699bde0(transitive)
- Removed@solana/functional@2.0.0-experimental.699bde0(transitive)
- Removed@solana/keys@2.0.0-experimental.699bde0(transitive)
- Removed@solana/transactions@2.0.0-experimental.699bde0(transitive)