algosdk 3.5.2 → 3.7.0-beta.1

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 (133) 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/appAccess.js +8 -5
  5. package/dist/cjs/appAccess.js.map +1 -1
  6. package/dist/cjs/client/v2/algod/accountApplicationsInformation.js +38 -0
  7. package/dist/cjs/client/v2/algod/accountApplicationsInformation.js.map +1 -0
  8. package/dist/cjs/client/v2/algod/accountAssetsInformation.js +31 -0
  9. package/dist/cjs/client/v2/algod/accountAssetsInformation.js.map +1 -0
  10. package/dist/cjs/client/v2/algod/algod.js +23 -19
  11. package/dist/cjs/client/v2/algod/algod.js.map +1 -1
  12. package/dist/cjs/client/v2/algod/getApplicationBoxes.js +116 -5
  13. package/dist/cjs/client/v2/algod/getApplicationBoxes.js.map +1 -1
  14. package/dist/cjs/client/v2/algod/models/types.js +243 -452
  15. package/dist/cjs/client/v2/algod/models/types.js.map +1 -1
  16. package/dist/cjs/ed25519-signer.js +76 -0
  17. package/dist/cjs/ed25519-signer.js.map +1 -0
  18. package/dist/cjs/encoding/address.js +61 -1
  19. package/dist/cjs/encoding/address.js.map +1 -1
  20. package/dist/cjs/falcon-signer.js +17 -0
  21. package/dist/cjs/falcon-signer.js.map +1 -0
  22. package/dist/cjs/logicsig.js +201 -16
  23. package/dist/cjs/logicsig.js.map +1 -1
  24. package/dist/cjs/main.js +32 -63
  25. package/dist/cjs/main.js.map +1 -1
  26. package/dist/cjs/mnemonic/mnemonic.js +26 -1
  27. package/dist/cjs/mnemonic/mnemonic.js.map +1 -1
  28. package/dist/cjs/multisigSigning.js +78 -1
  29. package/dist/cjs/multisigSigning.js.map +1 -1
  30. package/dist/cjs/pq-signer.js +54 -0
  31. package/dist/cjs/pq-signer.js.map +1 -0
  32. package/dist/cjs/signedTransaction.js +15 -1
  33. package/dist/cjs/signedTransaction.js.map +1 -1
  34. package/dist/cjs/signer.js.map +1 -1
  35. package/dist/cjs/signing.js +94 -7
  36. package/dist/cjs/signing.js.map +1 -1
  37. package/dist/cjs/transaction.js +9 -1
  38. package/dist/cjs/transaction.js.map +1 -1
  39. package/dist/cjs/types/transactions/encoded.js +51 -1
  40. package/dist/cjs/types/transactions/encoded.js.map +1 -1
  41. package/dist/cjs/utils/ed25519-check.js +69 -0
  42. package/dist/cjs/utils/ed25519-check.js.map +1 -0
  43. package/dist/esm/appAccess.js +8 -5
  44. package/dist/esm/appAccess.js.map +1 -1
  45. package/dist/esm/client/v2/algod/accountApplicationsInformation.js +32 -0
  46. package/dist/esm/client/v2/algod/accountApplicationsInformation.js.map +1 -0
  47. package/dist/esm/client/v2/algod/accountAssetsInformation.js +25 -0
  48. package/dist/esm/client/v2/algod/accountAssetsInformation.js.map +1 -0
  49. package/dist/esm/client/v2/algod/algod.js +23 -19
  50. package/dist/esm/client/v2/algod/algod.js.map +1 -1
  51. package/dist/esm/client/v2/algod/getApplicationBoxes.js +116 -5
  52. package/dist/esm/client/v2/algod/getApplicationBoxes.js.map +1 -1
  53. package/dist/esm/client/v2/algod/models/types.js +239 -445
  54. package/dist/esm/client/v2/algod/models/types.js.map +1 -1
  55. package/dist/esm/ed25519-signer.js +72 -0
  56. package/dist/esm/ed25519-signer.js.map +1 -0
  57. package/dist/esm/encoding/address.js +58 -0
  58. package/dist/esm/encoding/address.js.map +1 -1
  59. package/dist/esm/falcon-signer.js +13 -0
  60. package/dist/esm/falcon-signer.js.map +1 -0
  61. package/dist/esm/logicsig.js +200 -15
  62. package/dist/esm/logicsig.js.map +1 -1
  63. package/dist/esm/main.js +8 -56
  64. package/dist/esm/main.js.map +1 -1
  65. package/dist/esm/mnemonic/mnemonic.js +25 -1
  66. package/dist/esm/mnemonic/mnemonic.js.map +1 -1
  67. package/dist/esm/multisigSigning.js +75 -0
  68. package/dist/esm/multisigSigning.js.map +1 -1
  69. package/dist/esm/pq-signer.js +50 -0
  70. package/dist/esm/pq-signer.js.map +1 -0
  71. package/dist/esm/signedTransaction.js +16 -2
  72. package/dist/esm/signedTransaction.js.map +1 -1
  73. package/dist/esm/signer.js.map +1 -1
  74. package/dist/esm/signing.js +91 -8
  75. package/dist/esm/signing.js.map +1 -1
  76. package/dist/esm/transaction.js +9 -1
  77. package/dist/esm/transaction.js.map +1 -1
  78. package/dist/esm/types/transactions/encoded.js +49 -1
  79. package/dist/esm/types/transactions/encoded.js.map +1 -1
  80. package/dist/esm/utils/ed25519-check.js +65 -0
  81. package/dist/esm/utils/ed25519-check.js.map +1 -0
  82. package/dist/types/client/v2/algod/accountApplicationsInformation.d.ts +16 -0
  83. package/dist/types/client/v2/algod/accountAssetsInformation.d.ts +12 -0
  84. package/dist/types/client/v2/algod/algod.d.ts +19 -17
  85. package/dist/types/client/v2/algod/getApplicationBoxes.d.ts +100 -5
  86. package/dist/types/client/v2/algod/models/types.d.ts +146 -232
  87. package/dist/types/ed25519-signer.d.ts +7 -0
  88. package/dist/types/encoding/address.d.ts +37 -0
  89. package/dist/types/falcon-signer.d.ts +11 -0
  90. package/dist/types/logicsig.d.ts +72 -1
  91. package/dist/types/main.d.ts +8 -44
  92. package/dist/types/mnemonic/mnemonic.d.ts +13 -0
  93. package/dist/types/multisigSigning.d.ts +49 -0
  94. package/dist/types/pq-signer.d.ts +8 -0
  95. package/dist/types/signedTransaction.d.ts +7 -2
  96. package/dist/types/signer.d.ts +38 -0
  97. package/dist/types/signing.d.ts +45 -0
  98. package/dist/types/transaction.d.ts +9 -0
  99. package/dist/types/types/transactions/encoded.d.ts +27 -0
  100. package/dist/types/utils/ed25519-check.d.ts +10 -0
  101. package/package.json +2 -1
  102. package/src/appAccess.ts +10 -5
  103. package/src/client/v2/algod/accountApplicationsInformation.ts +46 -0
  104. package/src/client/v2/algod/accountAssetsInformation.ts +33 -0
  105. package/src/client/v2/algod/algod.ts +25 -20
  106. package/src/client/v2/algod/getApplicationBoxes.ts +123 -5
  107. package/src/client/v2/algod/models/types.ts +523 -846
  108. package/src/ed25519-signer.ts +125 -0
  109. package/src/encoding/address.ts +80 -0
  110. package/src/falcon-signer.ts +30 -0
  111. package/src/logicsig.ts +258 -16
  112. package/src/main.ts +30 -60
  113. package/src/mnemonic/mnemonic.ts +34 -1
  114. package/src/multisigSigning.ts +111 -0
  115. package/src/pq-signer.ts +90 -0
  116. package/src/signedTransaction.ts +24 -0
  117. package/src/signer.ts +53 -0
  118. package/src/signing.ts +109 -8
  119. package/src/transaction.ts +9 -1
  120. package/src/types/transactions/encoded.ts +88 -0
  121. package/src/utils/ed25519-check.ts +67 -0
  122. package/dist/cjs/client/v2/algod/dryrun.js +0 -34
  123. package/dist/cjs/client/v2/algod/dryrun.js.map +0 -1
  124. package/dist/cjs/dryrun.js +0 -214
  125. package/dist/cjs/dryrun.js.map +0 -1
  126. package/dist/esm/client/v2/algod/dryrun.js +0 -28
  127. package/dist/esm/client/v2/algod/dryrun.js.map +0 -1
  128. package/dist/esm/dryrun.js +0 -208
  129. package/dist/esm/dryrun.js.map +0 -1
  130. package/dist/types/client/v2/algod/dryrun.d.ts +0 -11
  131. package/dist/types/dryrun.d.ts +0 -28
  132. package/src/client/v2/algod/dryrun.ts +0 -38
  133. package/src/dryrun.ts +0 -292
@@ -0,0 +1,125 @@
1
+ import { Address } from './encoding/address.js';
2
+ import { encodeMsgpack } from './encoding/encoding.js';
3
+ import {
4
+ MSIG_PROGRAM_TAG,
5
+ PROGRAM_TAG,
6
+ SIGN_PROGRAM_DATA_PREFIX,
7
+ } from './logicsig.js';
8
+ import { addressFromMultisigPreImg, pksFromAddresses } from './multisig.js';
9
+ import { SignedTransaction } from './signedTransaction.js';
10
+ import {
11
+ AddressWithDelegatedLsigSigner,
12
+ AddressWithMxBytesSigner,
13
+ AddressWithProgramDataSigner,
14
+ AddressWithTransactionSigner,
15
+ DelegatedLsigSigner,
16
+ MxBytesSigner,
17
+ ProgramDataSigner,
18
+ TransactionSigner,
19
+ } from './signer.js';
20
+ import { SIGN_BYTES_PREFIX } from './signing.js';
21
+ import { Transaction } from './transaction.js';
22
+ import {
23
+ EncodedMultisig,
24
+ EncodedSubsig,
25
+ } from './types/transactions/encoded.js';
26
+ import { arrayEqual, concatArrays } from './utils/utils.js';
27
+
28
+ export interface Ed25519SigningKey {
29
+ ed25519PublicKey: Uint8Array;
30
+ ed25519Signer: (bytesToSign: Uint8Array) => Promise<Uint8Array>;
31
+ }
32
+
33
+ export function addressWithSignersFromRawEd25519Signer(
34
+ ed25519SigningKey: Ed25519SigningKey,
35
+ sendingAddress: Address = new Address(ed25519SigningKey.ed25519PublicKey)
36
+ ): AddressWithTransactionSigner &
37
+ AddressWithDelegatedLsigSigner &
38
+ AddressWithMxBytesSigner &
39
+ AddressWithProgramDataSigner {
40
+ const authAddress = new Address(ed25519SigningKey.ed25519PublicKey);
41
+ const { ed25519Signer: rawSigner } = ed25519SigningKey;
42
+
43
+ const txnSigner: TransactionSigner = async (
44
+ txnGroup: Transaction[],
45
+ indexesToSign: number[]
46
+ ) => {
47
+ const stxns: SignedTransaction[] = [];
48
+ for (const index of indexesToSign) {
49
+ const txn = txnGroup[index];
50
+ // eslint-disable-next-line no-await-in-loop
51
+ const sig = await rawSigner(txn.bytesToSign());
52
+ const stxn = new SignedTransaction({
53
+ txn,
54
+ sig,
55
+ sgnr: txn.sender.equals(authAddress) ? undefined : authAddress,
56
+ });
57
+
58
+ stxns.push(stxn);
59
+ }
60
+
61
+ return stxns.map((stxn) => encodeMsgpack(stxn));
62
+ };
63
+
64
+ const delegatedLsigSigner: DelegatedLsigSigner = async (lsig, msig) => {
65
+ if (msig) {
66
+ const pks = pksFromAddresses(msig.addrs);
67
+
68
+ const multisigAddr = addressFromMultisigPreImg({
69
+ version: msig.version,
70
+ threshold: msig.threshold,
71
+ pks,
72
+ });
73
+
74
+ const toBeSigned = concatArrays(
75
+ MSIG_PROGRAM_TAG,
76
+ multisigAddr.publicKey,
77
+ lsig.logic
78
+ );
79
+
80
+ const subsigs: EncodedSubsig[] = pks.map((pk) => ({ pk }));
81
+ const ourSubsig = subsigs.find((subsig) =>
82
+ arrayEqual(subsig.pk, authAddress.publicKey)
83
+ );
84
+ if (ourSubsig === undefined) {
85
+ throw Error(
86
+ `DelegatedLsigSigner could not find ${authAddress} as a signer in the multisig`
87
+ );
88
+ }
89
+
90
+ const sig = await rawSigner(toBeSigned);
91
+ ourSubsig.s = sig;
92
+ return {
93
+ address: authAddress,
94
+ lmsig: {
95
+ v: msig.version,
96
+ thr: msig.threshold,
97
+ subsig: subsigs,
98
+ } satisfies EncodedMultisig,
99
+ };
100
+ }
101
+
102
+ const toBeSigned = concatArrays(PROGRAM_TAG, lsig.logic);
103
+ const sig = await rawSigner(toBeSigned);
104
+ return { address: authAddress, sig };
105
+ };
106
+
107
+ const mxBytesSigner: MxBytesSigner = async (bytes: Uint8Array) => {
108
+ const bytesToSign = concatArrays(SIGN_BYTES_PREFIX, bytes);
109
+ return rawSigner(bytesToSign);
110
+ };
111
+
112
+ const programDataSigner: ProgramDataSigner = async (data, lsig) => {
113
+ const parts = concatArrays(lsig.address().publicKey, data);
114
+ const toBeSigned = concatArrays(SIGN_PROGRAM_DATA_PREFIX, parts);
115
+ return rawSigner(toBeSigned);
116
+ };
117
+
118
+ return {
119
+ address: sendingAddress,
120
+ programDataSigner,
121
+ txnSigner,
122
+ delegatedLsigSigner,
123
+ mxBytesSigner,
124
+ };
125
+ }
@@ -3,6 +3,10 @@ import * as nacl from '../nacl/naclWrappers.js';
3
3
  import * as utils from '../utils/utils.js';
4
4
  import { encodeUint64 } from './uint64.js';
5
5
  import { bytesToHex } from './binarydata.js';
6
+ import { couldBeCurvePoint } from '../utils/ed25519-check.js';
7
+ // Type-only: erased at runtime, so this does not create an import cycle with
8
+ // types/transactions/encoded.ts, which imports this module transitively.
9
+ import type { EncodedPQSig } from '../types/transactions/encoded.js';
6
10
 
7
11
  export const ALGORAND_ADDRESS_BYTE_LENGTH = 36;
8
12
  export const ALGORAND_CHECKSUM_BYTE_LENGTH = 4;
@@ -13,6 +17,23 @@ export const ALGORAND_ZERO_ADDRESS_STRING =
13
17
  export const MALFORMED_ADDRESS_ERROR_MSG = 'address seems to be malformed';
14
18
  export const CHECKSUM_ADDRESS_ERROR_MSG = 'wrong checksum for address';
15
19
 
20
+ /**
21
+ * The domain-separation prefix prepended to a post-quantum address preimage
22
+ * before hashing. Matches go-algorand's protocol.PostQuantumAddress HashID.
23
+ */
24
+ const PQ_ADDRESS_PREFIX = new TextEncoder().encode('PQA');
25
+
26
+ /**
27
+ * The required byte length of a post-quantum signature scheme identifier.
28
+ */
29
+ export const PQ_SCHEME_SIZE = 2;
30
+
31
+ /**
32
+ * The largest value a post-quantum address salt may take. The salt occupies a
33
+ * single byte of the address preimage.
34
+ */
35
+ export const PQ_SALT_MAX = 0xff;
36
+
16
37
  function checksumFromPublicKey(pk: Uint8Array): Uint8Array {
17
38
  return Uint8Array.from(
18
39
  nacl
@@ -178,3 +199,62 @@ export function getApplicationAddress(appID: number | bigint): Address {
178
199
  const hash = nacl.genericHash(toBeSigned);
179
200
  return new Address(Uint8Array.from(hash));
180
201
  }
202
+
203
+ /**
204
+ * Derive a post-quantum (PQ) account address together with the canonical salt
205
+ * used to derive it.
206
+ *
207
+ * @param schemeBytes - The 2-byte ASCII PQ scheme identifier (e.g. "f1" for Falcon-1024).
208
+ * @param key - The scheme's canonical public key.
209
+ * @returns The derived Address and the canonical 1-byte salt.
210
+ */
211
+ export function addressFromPQKey(
212
+ schemeBytes: Uint8Array,
213
+ key: Uint8Array
214
+ ): { address: Address; salt: number } {
215
+ if (schemeBytes.length !== PQ_SCHEME_SIZE)
216
+ throw new Error(
217
+ `invalid PQ scheme length: expected ${PQ_SCHEME_SIZE} bytes, got ${schemeBytes.length}`
218
+ );
219
+
220
+ // Rejection-sample the lowest salt that yields a PQ-compliant (non-Ed25519)
221
+ // address. The probability of exhausting the range is ~2^-256.
222
+ for (let salt = 0; salt <= PQ_SALT_MAX; salt++) {
223
+ const toBeHashed = utils.concatArrays(
224
+ PQ_ADDRESS_PREFIX,
225
+ schemeBytes,
226
+ Uint8Array.of(salt),
227
+ key
228
+ );
229
+ const publicKey = Uint8Array.from(nacl.genericHash(toBeHashed));
230
+ if (!couldBeCurvePoint(publicKey)) {
231
+ return { address: new Address(publicKey), salt };
232
+ }
233
+ }
234
+
235
+ throw new Error('no canonical salt exists for this PQ public key and scheme');
236
+ }
237
+
238
+ /**
239
+ * Derive the account address that a post-quantum signature authorizes.
240
+ *
241
+ * Unlike an Ed25519 signature, a PQ signature carries the scheme, salt and
242
+ * public key of the signing account, so the address it authorizes is fully
243
+ * determined by the signature and does not have to be supplied out of band.
244
+ *
245
+ * This also validates the signature's self-consistency: the salt must be the
246
+ * canonical one for the given scheme and public key, which is what the network
247
+ * requires.
248
+ *
249
+ * @param pqsig - The post-quantum signature to derive the address from.
250
+ * @returns The address of the account the signature authorizes.
251
+ */
252
+ export function addressFromPQSig(pqsig: EncodedPQSig): Address {
253
+ const { address, salt } = addressFromPQKey(pqsig.sch, pqsig.pk);
254
+ if (salt !== pqsig.slt) {
255
+ throw new Error(
256
+ `invalid PQ signature salt: expected the canonical salt ${salt}, got ${pqsig.slt}`
257
+ );
258
+ }
259
+ return address;
260
+ }
@@ -0,0 +1,30 @@
1
+ import { Address } from './encoding/address.js';
2
+ import {
3
+ AddressWithDelegatedLsigSigner,
4
+ AddressWithTransactionSigner,
5
+ } from './signer.js';
6
+ import { addressWithSignersFromRawPQSigner } from './pq-signer.js';
7
+
8
+ /**
9
+ * The 2-byte ASCII identifier of the Falcon-1024 post-quantum signature scheme.
10
+ */
11
+ export const FALCON_1024_SCHEME = new TextEncoder().encode('f1');
12
+
13
+ export interface Falcon1024SigningKey {
14
+ falcon1024PublicKey: Uint8Array;
15
+ falcon1024Signer: (bytesToSign: Uint8Array) => Promise<Uint8Array>;
16
+ }
17
+
18
+ export function addressWithSignersFromRawFalcon1024Signer(
19
+ falconSigningKey: Falcon1024SigningKey,
20
+ sendingAddress?: Address
21
+ ): AddressWithTransactionSigner & AddressWithDelegatedLsigSigner {
22
+ return addressWithSignersFromRawPQSigner(
23
+ {
24
+ pqScheme: FALCON_1024_SCHEME,
25
+ pqPublicKey: falconSigningKey.falcon1024PublicKey,
26
+ pqSigner: falconSigningKey.falcon1024Signer,
27
+ },
28
+ sendingAddress
29
+ );
30
+ }