algosdk 3.7.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +4 -4
  2. package/dist/browser/algosdk.min.js +1 -1
  3. package/dist/browser/algosdk.min.js.map +1 -1
  4. package/dist/cjs/client/v2/algod/getPeers.js +20 -0
  5. package/dist/cjs/client/v2/algod/getPeers.js.map +1 -0
  6. package/dist/cjs/ed25519-signer.js +18 -0
  7. package/dist/cjs/ed25519-signer.js.map +1 -1
  8. package/dist/cjs/encoding/address.js +9 -0
  9. package/dist/cjs/encoding/address.js.map +1 -1
  10. package/dist/cjs/falcon-signer.js +16 -0
  11. package/dist/cjs/falcon-signer.js.map +1 -1
  12. package/dist/cjs/logicsig.js +86 -6
  13. package/dist/cjs/logicsig.js.map +1 -1
  14. package/dist/cjs/mnemonic/mnemonic.js +2 -0
  15. package/dist/cjs/mnemonic/mnemonic.js.map +1 -1
  16. package/dist/cjs/pq-signer.js +25 -0
  17. package/dist/cjs/pq-signer.js.map +1 -1
  18. package/dist/cjs/signer.js.map +1 -1
  19. package/dist/cjs/signing.js +22 -0
  20. package/dist/cjs/signing.js.map +1 -1
  21. package/dist/cjs/types/block.js +28 -0
  22. package/dist/cjs/types/block.js.map +1 -1
  23. package/dist/esm/client/v2/algod/getPeers.js +14 -0
  24. package/dist/esm/client/v2/algod/getPeers.js.map +1 -0
  25. package/dist/esm/ed25519-signer.js +18 -0
  26. package/dist/esm/ed25519-signer.js.map +1 -1
  27. package/dist/esm/encoding/address.js +9 -0
  28. package/dist/esm/encoding/address.js.map +1 -1
  29. package/dist/esm/falcon-signer.js +16 -0
  30. package/dist/esm/falcon-signer.js.map +1 -1
  31. package/dist/esm/logicsig.js +86 -6
  32. package/dist/esm/logicsig.js.map +1 -1
  33. package/dist/esm/mnemonic/mnemonic.js +2 -0
  34. package/dist/esm/mnemonic/mnemonic.js.map +1 -1
  35. package/dist/esm/pq-signer.js +25 -0
  36. package/dist/esm/pq-signer.js.map +1 -1
  37. package/dist/esm/signer.js.map +1 -1
  38. package/dist/esm/signing.js +22 -0
  39. package/dist/esm/signing.js.map +1 -1
  40. package/dist/esm/types/block.js +28 -0
  41. package/dist/esm/types/block.js.map +1 -1
  42. package/dist/types/client/v2/algod/getPeers.d.ts +7 -0
  43. package/dist/types/ed25519-signer.d.ts +29 -0
  44. package/dist/types/encoding/address.d.ts +9 -0
  45. package/dist/types/falcon-signer.d.ts +27 -0
  46. package/dist/types/logicsig.d.ts +91 -6
  47. package/dist/types/mnemonic/mnemonic.d.ts +2 -0
  48. package/dist/types/pq-signer.d.ts +37 -0
  49. package/dist/types/signer.d.ts +68 -5
  50. package/dist/types/signing.d.ts +22 -0
  51. package/dist/types/types/block.d.ts +22 -0
  52. package/package.json +1 -1
  53. package/src/ed25519-signer.ts +29 -0
  54. package/src/encoding/address.ts +9 -0
  55. package/src/falcon-signer.ts +27 -0
  56. package/src/logicsig.ts +93 -6
  57. package/src/mnemonic/mnemonic.ts +2 -0
  58. package/src/pq-signer.ts +37 -0
  59. package/src/signer.ts +68 -5
  60. package/src/signing.ts +22 -0
  61. package/src/types/block.ts +54 -0
@@ -1,8 +1,45 @@
1
1
  import { Address } from './encoding/address.js';
2
2
  import { AddressWithDelegatedLsigSigner, AddressWithEmptyTransactionSigner, AddressWithTransactionSigner } from './signer.js';
3
+ /**
4
+ * A post-quantum public key, its scheme identifier, and a function that signs
5
+ * raw bytes with the corresponding secret key.
6
+ *
7
+ * @remarks
8
+ * `pqSigner` receives the exact bytes to sign, with every domain-separation
9
+ * prefix already applied, so it can be backed by a key that never leaves a
10
+ * wallet, HSM or hardware device.
11
+ */
3
12
  export interface PQSigningKey {
13
+ /** The 2-byte ASCII PQ scheme identifier (e.g. "f1" for Falcon-1024). */
4
14
  pqScheme: Uint8Array;
15
+ /** The scheme's canonical public key. */
5
16
  pqPublicKey: Uint8Array;
17
+ /** Signs the given bytes verbatim with the corresponding secret key. */
6
18
  pqSigner: (bytesToSign: Uint8Array) => Promise<Uint8Array>;
7
19
  }
20
+ /**
21
+ * Build the full set of signers for a post-quantum key from a function that
22
+ * signs raw bytes with it.
23
+ *
24
+ * @remarks
25
+ * The account address is derived from the scheme and public key via
26
+ * {@link addressFromPQKey}, so it does not have to be supplied. Every signature
27
+ * produced carries the scheme, canonical salt and public key alongside the
28
+ * signature bytes, which is what lets the network recover the authorizing
29
+ * address from the signature alone.
30
+ *
31
+ * PQ schemes cannot participate in multisig, so `delegatedLsigSigner` throws if
32
+ * given an `msig` argument, and no `mxBytesSigner` or `programDataSigner` is
33
+ * returned — signing arbitrary bytes and program data are ed25519-only
34
+ * operations.
35
+ *
36
+ * @param signingKey - The scheme, public key and raw signing function to build the signers from
37
+ * @param sendingAddress - The address transactions are sent from. Defaults to
38
+ * the derived PQ address; supply it when the PQ key is the auth address of a
39
+ * rekeyed account, in which case the produced transactions carry the derived
40
+ * address in their `sgnr` field.
41
+ * @returns An address bundled with transaction, empty transaction and delegated
42
+ * LogicSig signers
43
+ * @throws If `pqScheme` is not exactly 2 bytes
44
+ */
8
45
  export declare function addressWithSignersFromRawPQSigner(signingKey: PQSigningKey, sendingAddress?: Address): AddressWithTransactionSigner & AddressWithDelegatedLsigSigner & AddressWithEmptyTransactionSigner;
@@ -21,9 +21,24 @@ export interface Addressable {
21
21
  * corresponds to the signed transaction from txnGroup[indexesToSign[i]]
22
22
  */
23
23
  export type TransactionSigner = (txnGroup: Transaction[], indexesToSign: number[]) => Promise<Uint8Array[]>;
24
+ /**
25
+ * An address paired with a signer able to sign transactions on its behalf.
26
+ *
27
+ * @remarks
28
+ * `address` is the address transactions are sent from, which is not necessarily
29
+ * the address that authorizes them: for a rekeyed account the two differ, and
30
+ * `txnSigner` sets the transaction's `sgnr` field accordingly.
31
+ */
24
32
  export interface AddressWithTransactionSigner extends Addressable {
25
33
  txnSigner: TransactionSigner;
26
34
  }
35
+ /**
36
+ * An address paired with a signer that produces placeholder signatures for it.
37
+ *
38
+ * @remarks
39
+ * Useful for post-quantum accounts, whose real signatures are large and slow to
40
+ * produce, when only a simulation of the group is needed.
41
+ */
27
42
  export interface AddressWithEmptyTransactionSigner extends Addressable {
28
43
  /**
29
44
  * A TransactionSigner that produces unsigned (or placeholder-signed)
@@ -32,11 +47,26 @@ export interface AddressWithEmptyTransactionSigner extends Addressable {
32
47
  */
33
48
  emptyTxnSigner: TransactionSigner;
34
49
  }
35
- /** Function for signing logic signatures for delegation
36
- * @param lsig - The logic signature that is being signed for delegation
37
- * @param msig - Optional multisig account that should be set when a public key is signing as a subsigner of a multisig
38
- * @returns The address of the delegator
39
- * */
50
+ /**
51
+ * This type represents a function which can sign a LogicSig for delegation.
52
+ *
53
+ * @remarks
54
+ * Exactly one of `sig`, `lmsig` and `pqsig` is returned, according to the kind
55
+ * of key the signer holds and whether `msig` was supplied:
56
+ *
57
+ * - `sig` - an ed25519 signature from a single delegating account
58
+ * - `lmsig` - a multisig containing this signer's subsignature, returned when
59
+ * `msig` is supplied
60
+ * - `pqsig` - a post-quantum signature from a single delegating account
61
+ *
62
+ * @param lsig - The logic signature that is being signed for delegation
63
+ * @param msig - Optional multisig account that should be set when a public key is signing as a subsigner of a multisig
64
+ * @returns A promise which resolves to the signature and the address that
65
+ * produced it. When `msig` is omitted this is the delegating account; when
66
+ * `msig` is supplied it is the individual subsigner rather than the multisig.
67
+ * Either way it is an authorizing address, which is not necessarily the
68
+ * address the signer sends transactions from.
69
+ */
40
70
  export type DelegatedLsigSigner = (lsig: LogicSig, msig?: MultisigMetadata) => Promise<{
41
71
  address: Address;
42
72
  } & ({
@@ -46,14 +76,47 @@ export type DelegatedLsigSigner = (lsig: LogicSig, msig?: MultisigMetadata) => P
46
76
  } | {
47
77
  pqsig: EncodedPQSig;
48
78
  })>;
79
+ /**
80
+ * An address paired with a signer able to delegate a LogicSig to it.
81
+ */
49
82
  export interface AddressWithDelegatedLsigSigner extends Addressable {
50
83
  delegatedLsigSigner: DelegatedLsigSigner;
51
84
  }
85
+ /**
86
+ * This type represents a function which can sign arbitrary bytes, for use with
87
+ * {@link verifyBytes}.
88
+ *
89
+ * @remarks
90
+ * The implementation is responsible for prepending the "MX" domain-separation
91
+ * prefix ({@link SIGN_BYTES_PREFIX}) before signing, so `bytesToSign` is the
92
+ * caller's bytes alone.
93
+ *
94
+ * @param bytesToSign - The bytes to sign, without any domain-separation prefix
95
+ * @returns A promise which resolves to the raw signature
96
+ */
52
97
  export type MxBytesSigner = (bytesToSign: Uint8Array) => Promise<Uint8Array>;
98
+ /**
99
+ * An address paired with a signer able to sign arbitrary bytes on its behalf.
100
+ */
53
101
  export interface AddressWithMxBytesSigner extends Addressable {
54
102
  mxBytesSigner: MxBytesSigner;
55
103
  }
104
+ /**
105
+ * This type represents a function which can sign data for use with the
106
+ * `ed25519verify` opcode from within a LogicSig's program.
107
+ *
108
+ * @remarks
109
+ * The implementation is responsible for prepending the "ProgData" prefix
110
+ * ({@link SIGN_PROGRAM_DATA_PREFIX}) and the LogicSig's address before signing.
111
+ *
112
+ * @param data - The data to sign, without any prefix
113
+ * @param lsig - The LogicSig whose program will verify the signature
114
+ * @returns A promise which resolves to the raw signature
115
+ */
56
116
  export type ProgramDataSigner = (data: Uint8Array, lsig: LogicSig) => Promise<Uint8Array>;
117
+ /**
118
+ * An address paired with a signer able to sign program data on its behalf.
119
+ */
57
120
  export interface AddressWithProgramDataSigner extends Addressable {
58
121
  programDataSigner: ProgramDataSigner;
59
122
  }
@@ -3,6 +3,11 @@ import { SignedTransaction } from './signedTransaction.js';
3
3
  import { Transaction } from './transaction.js';
4
4
  import { LogicSig, LogicSigAccount } from './logicsig.js';
5
5
  import type { TransactionSigner } from './signer.js';
6
+ /**
7
+ * The domain-separation prefix prepended to arbitrary bytes before signing them
8
+ * with {@link signBytes}, so that such a signature can never be mistaken for a
9
+ * signature over a transaction or a program.
10
+ */
6
11
  export declare const SIGN_BYTES_PREFIX: Uint8Array;
7
12
  /**
8
13
  * @deprecated Use signTransactionWithSigner
@@ -25,6 +30,23 @@ export declare function signTransaction(txn: Transaction, sk: Uint8Array): {
25
30
  txID: string;
26
31
  blob: Uint8Array;
27
32
  };
33
+ /**
34
+ * signTransactionWithSigner signs a single transaction with the given signer.
35
+ *
36
+ * @remarks
37
+ * This is the replacement for the deprecated {@link signTransaction}, which can
38
+ * only sign with a raw ed25519 secret key. Because a `TransactionSigner` signs
39
+ * a group, the transaction is passed as a one-element group and the single
40
+ * result is returned.
41
+ *
42
+ * The decoded `stxn` is returned alongside the blob so callers can read what
43
+ * the signer produced — its `sig`, `pqsig` or `msig` field, and the `sgnr` field
44
+ * naming the key that signed when it is not the transaction sender.
45
+ *
46
+ * @param txn - the transaction to sign
47
+ * @param signer - the signer to sign with
48
+ * @returns an object with blob, txID and stxn properties
49
+ */
28
50
  export declare function signTransactionWithSigner(txn: Transaction, signer: TransactionSigner): Promise<ReturnType<typeof signTransaction> & {
29
51
  stxn: SignedTransaction;
30
52
  }>;
@@ -49,9 +49,14 @@ export declare class TxnCommitments implements Encodable {
49
49
  * Root of transaction vector commitment merkle tree using SHA256 hash function
50
50
  */
51
51
  sha256Commitment: Uint8Array;
52
+ /**
53
+ * Root of transaction vector commitment merkle tree using SHA512 hash function
54
+ */
55
+ sha512Commitment: Uint8Array;
52
56
  constructor(params: {
53
57
  nativeSha512_256Commitment: Uint8Array;
54
58
  sha256Commitment: Uint8Array;
59
+ sha512Commitment?: Uint8Array;
55
60
  });
56
61
  getEncodingSchema(): Schema;
57
62
  toEncodingData(): Map<string, unknown>;
@@ -196,6 +201,10 @@ export declare class BlockHeader implements Encodable {
196
201
  * Previous block hash
197
202
  */
198
203
  branch: Uint8Array;
204
+ /**
205
+ * Previous block hash, using SHA-512
206
+ */
207
+ branch512: Uint8Array;
199
208
  /**
200
209
  * Sortition seed
201
210
  */
@@ -249,9 +258,20 @@ export declare class BlockHeader implements Encodable {
249
258
  */
250
259
  stateproofTracking: Map<number, StateProofTrackingData>;
251
260
  participationUpdates: ParticipationUpdates;
261
+ /**
262
+ * Load is the degree to which a block is full. Currently, it is based on the number of bytes in
263
+ * the final block, compared to the maximum allowed. It is expressed as a fixed-point integer with
264
+ * 6 digits of precision. So, 1,000,000 is a completely full block.
265
+ */
266
+ load: bigint;
267
+ /**
268
+ * CongestionTax is the fee required, beyond the MinFee, for "normal" transactions in this block.
269
+ */
270
+ congestionTax: bigint;
252
271
  constructor(params: {
253
272
  round: bigint;
254
273
  branch: Uint8Array;
274
+ branch512?: Uint8Array;
255
275
  seed: Uint8Array;
256
276
  txnCommitments: TxnCommitments;
257
277
  timestamp: bigint;
@@ -267,6 +287,8 @@ export declare class BlockHeader implements Encodable {
267
287
  txnCounter: bigint;
268
288
  stateproofTracking: Map<number, StateProofTrackingData>;
269
289
  participationUpdates: ParticipationUpdates;
290
+ load?: bigint;
291
+ congestionTax?: bigint;
270
292
  });
271
293
  getEncodingSchema(): Schema;
272
294
  toEncodingData(): Map<string, unknown>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "algosdk",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "description": "The official JavaScript SDK for Algorand",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -25,11 +25,40 @@ import {
25
25
  } from './types/transactions/encoded.js';
26
26
  import { arrayEqual, concatArrays } from './utils/utils.js';
27
27
 
28
+ /**
29
+ * An ed25519 public key paired with a function that signs raw bytes with the
30
+ * corresponding secret key.
31
+ *
32
+ * @remarks
33
+ * `ed25519Signer` receives the exact bytes to sign, with every
34
+ * domain-separation prefix already applied, so it can be backed by a key that
35
+ * never leaves a wallet, HSM or hardware device.
36
+ */
28
37
  export interface Ed25519SigningKey {
38
+ /** The 32-byte ed25519 public key. */
29
39
  ed25519PublicKey: Uint8Array;
40
+ /** Signs the given bytes verbatim with the corresponding secret key. */
30
41
  ed25519Signer: (bytesToSign: Uint8Array) => Promise<Uint8Array>;
31
42
  }
32
43
 
44
+ /**
45
+ * Build the full set of signers for an ed25519 key from a function that signs
46
+ * raw bytes with it.
47
+ *
48
+ * @remarks
49
+ * Each returned signer applies the domain separation its use requires
50
+ * ("Program", "MsigProgram", "ProgData", or the transaction prefix) before
51
+ * calling `ed25519Signer`, so a caller only has to supply the raw signing
52
+ * operation once.
53
+ *
54
+ * @param ed25519SigningKey - The public key and raw signing function to build the signers from
55
+ * @param sendingAddress - The address transactions are sent from. Defaults to
56
+ * the address of `ed25519PublicKey`; supply it when that key is the auth
57
+ * address of a rekeyed account, in which case the produced transactions carry
58
+ * the key's address in their `sgnr` field.
59
+ * @returns An address bundled with transaction, delegated LogicSig, arbitrary
60
+ * bytes and program data signers
61
+ */
33
62
  export function addressWithSignersFromRawEd25519Signer(
34
63
  ed25519SigningKey: Ed25519SigningKey,
35
64
  sendingAddress: Address = new Address(ed25519SigningKey.ed25519PublicKey)
@@ -204,9 +204,16 @@ export function getApplicationAddress(appID: number | bigint): Address {
204
204
  * Derive a post-quantum (PQ) account address together with the canonical salt
205
205
  * used to derive it.
206
206
  *
207
+ * @remarks
208
+ * The salt is found by rejection sampling: it is the lowest value whose
209
+ * preimage hashes to something that could not also be an Ed25519 public key, so
210
+ * that a PQ account can never collide with an Ed25519 one.
211
+ *
207
212
  * @param schemeBytes - The 2-byte ASCII PQ scheme identifier (e.g. "f1" for Falcon-1024).
208
213
  * @param key - The scheme's canonical public key.
209
214
  * @returns The derived Address and the canonical 1-byte salt.
215
+ * @throws If `schemeBytes` is not exactly {@link PQ_SCHEME_SIZE} bytes, or in
216
+ * the ~2^-256 case where no salt in range yields a valid address.
210
217
  */
211
218
  export function addressFromPQKey(
212
219
  schemeBytes: Uint8Array,
@@ -248,6 +255,8 @@ export function addressFromPQKey(
248
255
  *
249
256
  * @param pqsig - The post-quantum signature to derive the address from.
250
257
  * @returns The address of the account the signature authorizes.
258
+ * @throws If the signature's scheme is malformed, or if its salt is not the
259
+ * canonical one for its scheme and public key.
251
260
  */
252
261
  export function addressFromPQSig(pqsig: EncodedPQSig): Address {
253
262
  const { address, salt } = addressFromPQKey(pqsig.sch, pqsig.pk);
@@ -11,11 +11,38 @@ import { addressWithSignersFromRawPQSigner } from './pq-signer.js';
11
11
  */
12
12
  export const FALCON_1024_SCHEME = new TextEncoder().encode('f1');
13
13
 
14
+ /**
15
+ * A Falcon-1024 public key paired with a function that signs raw bytes with the
16
+ * corresponding secret key.
17
+ *
18
+ * @remarks
19
+ * `falcon1024Signer` receives the exact bytes to sign, with every
20
+ * domain-separation prefix already applied, so it can be backed by a key that
21
+ * never leaves a wallet, HSM or hardware device.
22
+ */
14
23
  export interface Falcon1024SigningKey {
24
+ /** The Falcon-1024 public key. */
15
25
  falcon1024PublicKey: Uint8Array;
26
+ /** Signs the given bytes verbatim with the corresponding secret key. */
16
27
  falcon1024Signer: (bytesToSign: Uint8Array) => Promise<Uint8Array>;
17
28
  }
18
29
 
30
+ /**
31
+ * Build the full set of signers for a Falcon-1024 key from a function that
32
+ * signs raw bytes with it.
33
+ *
34
+ * @remarks
35
+ * A thin wrapper around {@link addressWithSignersFromRawPQSigner} that supplies
36
+ * the {@link FALCON_1024_SCHEME} identifier, so see that function for the
37
+ * details and limitations of post-quantum signing.
38
+ *
39
+ * @param falconSigningKey - The public key and raw signing function to build the signers from
40
+ * @param sendingAddress - The address transactions are sent from. Defaults to
41
+ * the derived Falcon-1024 address; supply it when this key is the auth
42
+ * address of a rekeyed account.
43
+ * @returns An address bundled with transaction, empty transaction and delegated
44
+ * LogicSig signers
45
+ */
19
46
  export function addressWithSignersFromRawFalcon1024Signer(
20
47
  falconSigningKey: Falcon1024SigningKey,
21
48
  sendingAddress?: Address
package/src/logicsig.ts CHANGED
@@ -68,8 +68,22 @@ export function sanityCheckProgram(program: Uint8Array) {
68
68
  }
69
69
  }
70
70
 
71
+ /**
72
+ * The domain-separation prefix prepended to a program before it is hashed into
73
+ * an escrow address, or signed for delegation by a single ed25519 account.
74
+ */
71
75
  export const PROGRAM_TAG = new TextEncoder().encode('Program');
76
+
77
+ /**
78
+ * The domain-separation prefix prepended to a post-quantum delegating account's
79
+ * address and a program before the program is signed for delegation.
80
+ */
72
81
  export const PQ_PROGRAM_TAG = new TextEncoder().encode('PQProgram');
82
+
83
+ /**
84
+ * The domain-separation prefix prepended to a delegating multisig account's
85
+ * address and a program before the program is signed for delegation.
86
+ */
73
87
  export const MSIG_PROGRAM_TAG = new TextEncoder().encode('MsigProgram');
74
88
 
75
89
  /**
@@ -112,6 +126,11 @@ export class LogicSig implements encoding.Encodable {
112
126
  sig?: Uint8Array;
113
127
  msig?: EncodedMultisig;
114
128
  lmsig?: EncodedMultisig;
129
+ /**
130
+ * The post-quantum delegation signature, if the delegating account is a
131
+ * post-quantum account. At most one of `sig`, `msig`, `lmsig` and `pqsig` may
132
+ * be set.
133
+ */
115
134
  pqsig?: EncodedPQSig;
116
135
 
117
136
  constructor(program: Uint8Array, programArgs?: Array<Uint8Array> | null) {
@@ -276,6 +295,11 @@ export class LogicSig implements encoding.Encodable {
276
295
  /**
277
296
  * Signs this LogicSig for delegation using the given signer.
278
297
  *
298
+ * @remarks
299
+ * Re-signing an already-signed LogicSig is allowed, and replaces the previous
300
+ * delegation signature. At most one of `sig`, `msig`, `lmsig` and `pqsig` may
301
+ * be set, so any signature left over from an earlier call is cleared.
302
+ *
279
303
  * @param signer - The signer to delegate to
280
304
  * @param msig - Optional multisig account the signer is a subsigner of
281
305
  * @returns The address the signer signed as. When `msig` is omitted this is
@@ -283,10 +307,9 @@ export class LogicSig implements encoding.Encodable {
283
307
  * subsigner, not the multisig, so the delegating account is
284
308
  * `multisigAddress(msig)`. Either way it is an authorizing address, which
285
309
  * is not necessarily the address a signer sends transactions from.
286
- *
287
- * Re-signing an already-signed LogicSig is allowed, and replaces the previous
288
- * delegation signature. At most one of `sig`, `msig`, `lmsig` and `pqsig` may
289
- * be set, so any signature left over from an earlier call is cleared.
310
+ * @throws If the signer returns a signature of the wrong kind for the
311
+ * requested delegation, or an `lmsig` whose version, threshold or public
312
+ * keys do not match `msig`
290
313
  */
291
314
  async signWithSigner(
292
315
  signer: DelegatedLsigSigner,
@@ -360,6 +383,24 @@ export class LogicSig implements encoding.Encodable {
360
383
  this.lmsig.subsig[index].s = sig;
361
384
  }
362
385
 
386
+ /**
387
+ * Appends an additional subsignature to this LogicSig's existing multisig
388
+ * delegation.
389
+ *
390
+ * @remarks
391
+ * The multisig preimage is taken from the `lmsig` already on this LogicSig,
392
+ * so {@link signWithSigner} must have been called with an `msig` argument
393
+ * first. The signer must hold a key belonging to that multisig.
394
+ *
395
+ * A signature already collected from another member is never silently
396
+ * replaced: if the signer returns a different signature for a subsig that is
397
+ * already filled in, this throws instead.
398
+ *
399
+ * @param signer - The signer to append a subsignature from
400
+ * @throws If there is no multisig on this LogicSig, if the signer returns no
401
+ * signature, a signature for a key outside the multisig, or one that
402
+ * conflicts with a signature already collected
403
+ */
363
404
  async appendToMultisigWithSigner(signer: DelegatedLsigSigner) {
364
405
  if (this.lmsig === undefined) {
365
406
  throw new Error('no multisig present');
@@ -475,8 +516,15 @@ export class LogicSig implements encoding.Encodable {
475
516
  * Signs arbitrary data for use with the `ed25519verify` opcode from within
476
517
  * this LogicSig's program.
477
518
  *
519
+ * @remarks
520
+ * This does not modify the LogicSig or delegate it; the LogicSig is only used
521
+ * for the address that domain-separates the signature. The program is
522
+ * responsible for verifying the returned signature against the signer's
523
+ * public key.
524
+ *
478
525
  * @param signer - The signer to sign the data with
479
526
  * @param data - The data to sign
527
+ * @returns A promise which resolves to the raw signature over the data
480
528
  */
481
529
  async signDataWithSigner(signer: ProgramDataSigner, data: Uint8Array) {
482
530
  return signer(data, this);
@@ -656,6 +704,22 @@ export class LogicSigAccount implements encoding.Encodable {
656
704
  this.lsig.sign(secretKey, msig);
657
705
  }
658
706
 
707
+ /**
708
+ * Turns this LogicSigAccount into a delegated LogicSig, signed by one member
709
+ * of a delegating multisig account.
710
+ *
711
+ * @remarks
712
+ * This produces a LogicSig with a single subsignature filled in. Unless the
713
+ * multisig's threshold is 1, call {@link LogicSigAccount.appendToMultisigWithSigner}
714
+ * with the remaining members' signers before the LogicSig can authorize
715
+ * transactions.
716
+ *
717
+ * If the delegating account is not a multisig, use
718
+ * {@link LogicSigAccount.signWithSigner} instead.
719
+ *
720
+ * @param msig - The multisig delegating to this LogicSig
721
+ * @param signer - The signer of one member of `msig`
722
+ */
659
723
  async signMultisigWithSigner(
660
724
  msig: MultisigMetadata,
661
725
  signer: DelegatedLsigSigner
@@ -676,6 +740,16 @@ export class LogicSigAccount implements encoding.Encodable {
676
740
  this.lsig.appendToMultisig(secretKey);
677
741
  }
678
742
 
743
+ /**
744
+ * Adds an additional signature from a member of the delegating multisig
745
+ * account.
746
+ *
747
+ * @remarks
748
+ * {@link LogicSigAccount.signMultisigWithSigner} must have been called first
749
+ * to establish the multisig this signature belongs to.
750
+ *
751
+ * @param signer - The signer of another member of the delegating multisig account
752
+ */
679
753
  async appendToMultisigWithSigner(signer: DelegatedLsigSigner) {
680
754
  await this.lsig.appendToMultisigWithSigner(signer);
681
755
  }
@@ -697,8 +771,17 @@ export class LogicSigAccount implements encoding.Encodable {
697
771
 
698
772
  /**
699
773
  * Turns this LogicSigAccount into a delegated LogicSig, signed by the given
700
- * signer. If the delegating account is a multisig account, use
701
- * `signMultisigWithSigner` instead.
774
+ * signer. This type of LogicSig has the authority to sign transactions on
775
+ * behalf of another account, called the delegating account.
776
+ *
777
+ * @remarks
778
+ * If the delegating account is a multisig account, use
779
+ * {@link LogicSigAccount.signMultisigWithSigner} instead.
780
+ *
781
+ * The delegating account is taken to be the address the signer reports having
782
+ * signed as, not any sending address the signer advertises: for a rekeyed
783
+ * account the latter is the address it sends transactions from, which is not
784
+ * the account authorizing this delegation.
702
785
  *
703
786
  * @param signer - The signer of the delegating account.
704
787
  */
@@ -720,6 +803,10 @@ export function logicSigFromByte(encoded: Uint8Array): LogicSig {
720
803
  return encoding.decodeMsgpack(encoded, LogicSig);
721
804
  }
722
805
 
806
+ /**
807
+ * The domain-separation prefix prepended, along with the program's address, to
808
+ * data signed for verification by the `ed25519verify` opcode.
809
+ */
723
810
  export const SIGN_PROGRAM_DATA_PREFIX = new TextEncoder().encode('ProgData');
724
811
 
725
812
  /**
@@ -198,6 +198,8 @@ const PQ_KEY_PREFIX = new TextEncoder().encode('PQK');
198
198
  * @param mn - A 25-word Algorand mnemonic
199
199
  * @param scheme - The 2-byte ASCII PQ scheme identifier (e.g. "f1" for Falcon-1024)
200
200
  * @returns The 32-byte seed to hand to the scheme's key generator
201
+ * @throws If `mn` is not a valid 25-word mnemonic, or if `scheme` is not
202
+ * exactly {@link PQ_SCHEME_SIZE} bytes
201
203
  */
202
204
  export function pq25WordMnemonicToSeed(
203
205
  mn: string,
package/src/pq-signer.ts CHANGED
@@ -14,12 +14,49 @@ import { Transaction } from './transaction.js';
14
14
  import { EncodedPQSig } from './types/transactions/encoded.js';
15
15
  import { concatArrays } from './utils/utils.js';
16
16
 
17
+ /**
18
+ * A post-quantum public key, its scheme identifier, and a function that signs
19
+ * raw bytes with the corresponding secret key.
20
+ *
21
+ * @remarks
22
+ * `pqSigner` receives the exact bytes to sign, with every domain-separation
23
+ * prefix already applied, so it can be backed by a key that never leaves a
24
+ * wallet, HSM or hardware device.
25
+ */
17
26
  export interface PQSigningKey {
27
+ /** The 2-byte ASCII PQ scheme identifier (e.g. "f1" for Falcon-1024). */
18
28
  pqScheme: Uint8Array;
29
+ /** The scheme's canonical public key. */
19
30
  pqPublicKey: Uint8Array;
31
+ /** Signs the given bytes verbatim with the corresponding secret key. */
20
32
  pqSigner: (bytesToSign: Uint8Array) => Promise<Uint8Array>;
21
33
  }
22
34
 
35
+ /**
36
+ * Build the full set of signers for a post-quantum key from a function that
37
+ * signs raw bytes with it.
38
+ *
39
+ * @remarks
40
+ * The account address is derived from the scheme and public key via
41
+ * {@link addressFromPQKey}, so it does not have to be supplied. Every signature
42
+ * produced carries the scheme, canonical salt and public key alongside the
43
+ * signature bytes, which is what lets the network recover the authorizing
44
+ * address from the signature alone.
45
+ *
46
+ * PQ schemes cannot participate in multisig, so `delegatedLsigSigner` throws if
47
+ * given an `msig` argument, and no `mxBytesSigner` or `programDataSigner` is
48
+ * returned — signing arbitrary bytes and program data are ed25519-only
49
+ * operations.
50
+ *
51
+ * @param signingKey - The scheme, public key and raw signing function to build the signers from
52
+ * @param sendingAddress - The address transactions are sent from. Defaults to
53
+ * the derived PQ address; supply it when the PQ key is the auth address of a
54
+ * rekeyed account, in which case the produced transactions carry the derived
55
+ * address in their `sgnr` field.
56
+ * @returns An address bundled with transaction, empty transaction and delegated
57
+ * LogicSig signers
58
+ * @throws If `pqScheme` is not exactly 2 bytes
59
+ */
23
60
  export function addressWithSignersFromRawPQSigner(
24
61
  signingKey: PQSigningKey,
25
62
  sendingAddress?: Address