UNPKG

@pact-toolbox/signers

Version:
1 lines 13.5 kB
{"version":3,"file":"index.browser.cjs","names":["value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}","keyPairs: CryptoKeyPair[]","command: PactCommand","sigs: TransactionSig[]","sig: TransactionSig","transaction: unknown","transaction: PartiallySignedTransaction","value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}","value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}","keyPair: CryptoKeyPair","out: KeyPairSigner","bytes: ReadonlyUint8Array","extractable?: boolean","privateKey: string","address: Address","out: NoopSigner","content: Uint8Array | string","signatures: SignatureDictionary","TextEncoder"],"sources":["../src/command-signer.ts","../src/message-signer.ts","../src/keypair-signer.ts","../src/noop.ts","../src/signable-message.ts"],"sourcesContent":["import type { Address } from \"@pact-toolbox/crypto\";\nimport type {\n PactCommand,\n PartiallySignedTransaction,\n SignedTransaction,\n TransactionFullSig,\n TransactionSig,\n} from \"@pact-toolbox/types\";\n\nimport { base16, base64Url, blake2b, exportBase16Key, signBytes, utf8 } from \"@pact-toolbox/crypto\";\n\nimport type { BaseTransactionSignerConfig } from \"./types\";\n\nexport type PactCommandSignerConfig = BaseTransactionSignerConfig;\n\n/** Defines a signer capable of signing transactions. */\nexport type PactCommandSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signPactCommands(commands: PactCommand[]): Promise<PartiallySignedTransaction[]>;\n}>;\n\n/** Checks whether the provided value implements the {@link PactCommandSigner} interface. */\nexport function isPactCommandSigner<TAddress extends string>(value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}): value is PactCommandSigner<TAddress> {\n return \"signPactCommands\" in value && typeof value.signPactCommands === \"function\";\n}\n\n/** Asserts that the provided value implements the {@link PactCommandSigner} interface. */\nexport function assertIsPactCommandSigner<TAddress extends string>(value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}): asserts value is PactCommandSigner<TAddress> {\n if (!isPactCommandSigner(value)) {\n throw new Error(\"Value is not a PactCommandSigner\");\n }\n}\n\n// Function to sign a PactCommand\nexport async function partiallySignPactCommand(\n keyPairs: CryptoKeyPair[],\n command: PactCommand,\n): Promise<PartiallySignedTransaction> {\n // Step 1: JSON.stringify the command\n const cmd = JSON.stringify(command);\n\n // Step 2: Hash the stringified command with blake2b from blakejs\n const cmdBytes = utf8.encode(cmd);\n const hash = blake2b(cmdBytes as Uint8Array, undefined, 32); // 32-byte hash\n\n // Step 4: Sign the hash with keypairs found in signers field from the PactCommand\n // Map public keys to keyPairs for quick lookup\n const keyPairMap = new Map<string, CryptoKeyPair>();\n for (const keyPair of keyPairs) {\n const pubKeyHex = await exportBase16Key(keyPair.publicKey);\n keyPairMap.set(pubKeyHex, keyPair);\n }\n\n // Prepare the sigs array\n const sigs: TransactionSig[] = [];\n\n for (const signer of command.signers) {\n const pubKey = signer.pubKey;\n const keyPair = keyPairMap.get(pubKey);\n\n if (!keyPair) {\n // If we don't have the keyPair for this pubKey, add an empty signature\n sigs.push({ pubKey });\n continue;\n }\n\n // Sign the hash bytes\n const signatureBytes = await signBytes(keyPair.privateKey, hash);\n const signatureHex = base16.decode(signatureBytes);\n\n sigs.push({ pubKey, sig: signatureHex });\n }\n\n // Step 5: Build the SignedTransaction object with the signatures\n return {\n cmd,\n hash,\n sigs,\n };\n}\n\nexport function isTransactionFullSig(sig: TransactionSig): sig is TransactionFullSig {\n return \"sig\" in sig && sig.sig !== undefined;\n}\n\nexport function isFullySignedTransaction(transaction: unknown): transaction is SignedTransaction {\n return (\n typeof transaction === \"object\" &&\n transaction !== null &&\n \"cmd\" in transaction &&\n \"hash\" in transaction &&\n \"sigs\" in transaction &&\n Array.isArray(transaction.sigs) &&\n transaction.sigs.every(isTransactionFullSig)\n );\n}\n\nexport function finalizeTransaction(transaction: PartiallySignedTransaction): SignedTransaction {\n return Object.freeze({\n cmd: transaction.cmd,\n hash:\n typeof transaction.hash !== \"string\" && transaction.hash instanceof Uint8Array\n ? base64Url.decode(transaction.hash)\n : transaction.hash,\n sigs: transaction.sigs.filter((sig) => \"sig\" in sig) as TransactionFullSig[],\n });\n}\n","import type { Address } from \"@pact-toolbox/crypto\";\n\nimport type { SignableMessage } from \"./signable-message\";\nimport type { BaseSignerConfig, SignatureDictionary } from \"./types\";\n\nexport type MessageSignerConfig = BaseSignerConfig;\n\n/** Defines a signer capable of signing messages. */\nexport type MessageSigner<TAddress extends string = string> = Readonly<{\n address: Address<TAddress>;\n signMessages(\n messages: readonly SignableMessage[],\n config?: MessageSignerConfig,\n ): Promise<readonly SignatureDictionary[]>;\n}>;\n\n/** Checks whether the provided value implements the {@link MessageSigner} interface. */\nexport function isMessageSigner<TAddress extends string>(value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}): value is MessageSigner<TAddress> {\n return \"signMessages\" in value && typeof value.signMessages === \"function\";\n}\n\n/** Asserts that the provided value implements the {@link MessageSigner} interface. */\nexport function assertIsMessageSigner<TAddress extends string>(value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}): asserts value is MessageSigner<TAddress> {\n if (!isMessageSigner(value)) {\n throw new Error(\"Value is not a MessageSigner\");\n }\n}\n","import type { Address, ReadonlyUint8Array } from \"@pact-toolbox/crypto\";\n\nimport {\n base16,\n createKeyPairFromBytes,\n createKeyPairFromPrivateKeyBytes,\n generateKeyPair,\n exportBase16Key,\n signBytes,\n} from \"@pact-toolbox/crypto\";\n\nimport type { PactCommandSigner } from \"./command-signer\";\nimport type { MessageSigner } from \"./message-signer\";\nimport { isPactCommandSigner, partiallySignPactCommand } from \"./command-signer\";\nimport { isMessageSigner } from \"./message-signer\";\n\n/** Defines a signer capable of signing messages and transactions using a CryptoKeyPair. */\nexport type KeyPairSigner<TAddress extends string = string> = MessageSigner<TAddress> &\n PactCommandSigner<TAddress> & { keyPair: CryptoKeyPair };\n\n/** Checks whether the provided value implements the {@link KeyPairSigner} interface. */\nexport function isKeyPairSigner<TAddress extends string>(value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}): value is KeyPairSigner<TAddress> {\n return (\n \"keyPair\" in value && typeof value.keyPair === \"object\" && isMessageSigner(value) && isPactCommandSigner(value)\n );\n}\n\n/** Asserts that the provided value implements the {@link KeyPairSigner} interface. */\nexport function assertIsKeyPairSigner<TAddress extends string>(value: {\n [key: string]: unknown;\n address: Address<TAddress>;\n}): asserts value is KeyPairSigner<TAddress> {\n if (!isKeyPairSigner(value)) {\n throw new Error(\"Value is not a KeyPairSigner\");\n }\n}\n\n/** Creates a KeyPairSigner from the provided Crypto KeyPair. */\nexport async function createSignerFromKeyPair(keyPair: CryptoKeyPair): Promise<KeyPairSigner> {\n const address = (await exportBase16Key(keyPair.publicKey)) as Address;\n\n const out: KeyPairSigner = {\n address,\n keyPair,\n signMessages: (messages) => {\n return Promise.all(\n messages.map(async (message) =>\n Object.freeze({\n [address]: await signBytes(keyPair.privateKey, message.content),\n }),\n ),\n );\n },\n signPactCommands: (commands) => {\n return Promise.all(commands.map((cmd) => partiallySignPactCommand([keyPair], cmd)));\n },\n };\n\n return Object.freeze(out);\n}\n\n/** Securely generates a signer capable of signing messages and transactions using a Crypto KeyPair. */\nexport async function generateKeyPairSigner(): Promise<KeyPairSigner> {\n return createSignerFromKeyPair(await generateKeyPair());\n}\n\n/** Creates a signer capable of signing messages and transactions using the 64 bytes of a KeyPair. */\nexport async function createKeyPairSignerFromBytes(\n bytes: ReadonlyUint8Array,\n extractable?: boolean,\n): Promise<KeyPairSigner> {\n return createSignerFromKeyPair(await createKeyPairFromBytes(bytes, extractable));\n}\n\n/** Creates a signer capable of signing messages and transactions using the 32 bytes of a private key. */\nexport async function createKeyPairSignerFromPrivateKeyBytes(\n bytes: ReadonlyUint8Array,\n extractable?: boolean,\n): Promise<KeyPairSigner> {\n return createSignerFromKeyPair(await createKeyPairFromPrivateKeyBytes(bytes, extractable));\n}\n\nexport async function createKeyPairSignerFromBase16PrivateKey(\n privateKey: string,\n extractable?: boolean,\n): Promise<KeyPairSigner> {\n return createKeyPairSignerFromPrivateKeyBytes(base16.encode(privateKey), extractable);\n}\n","import type { Address } from \"@pact-toolbox/crypto\";\n\nimport type { PactCommandSigner } from \"./command-signer\";\nimport type { MessageSigner } from \"./message-signer\";\n\n/** Defines a no-operation signer that pretends to partially sign messages and transactions. */\nexport type NoopSigner<TAddress extends string = string> = MessageSigner<TAddress> & PactCommandSigner<TAddress>;\n\n/** Creates a NoopSigner from the provided Address. */\nexport function createNoopSigner(address: Address): NoopSigner {\n const out: NoopSigner = {\n address,\n signMessages: (messages) => Promise.resolve(messages.map(() => Object.freeze({}))),\n signPactCommands: (commands) => Promise.resolve(commands.map(() => Object.freeze({}) as any)),\n };\n\n return Object.freeze(out);\n}\n","import { TextEncoder } from \"@pact-toolbox/crypto\";\nimport type { SignatureDictionary } from \"./types\";\n\n/** Defines a message that needs signing and its current set of signatures if any. */\nexport type SignableMessage = Readonly<{\n content: Uint8Array;\n signatures: SignatureDictionary;\n}>;\n\n/**\n * Creates a signable message from a provided content.\n * If a string is provided, it will be UTF-8 encoded.\n */\nexport function createSignableMessage(\n content: Uint8Array | string,\n signatures: SignatureDictionary = {},\n): SignableMessage {\n return Object.freeze({\n content: typeof content === \"string\" ? new TextEncoder().encode(content) : content,\n signatures: Object.freeze({ ...signatures }),\n });\n}\n"],"mappings":"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"}