@stellar/stellar-sdk 16.0.0-rc.1 → 16.0.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 (128) hide show
  1. package/README.md +22 -28
  2. package/dist/stellar-sdk-axios.js +245 -232
  3. package/dist/stellar-sdk-axios.js.map +1 -1
  4. package/dist/stellar-sdk-axios.min.js +1 -1
  5. package/dist/stellar-sdk-axios.min.js.map +1 -1
  6. package/dist/stellar-sdk.js +49 -36
  7. package/dist/stellar-sdk.js.map +1 -1
  8. package/dist/stellar-sdk.min.js +2 -2
  9. package/dist/stellar-sdk.min.js.map +1 -1
  10. package/lib/axios/cjs/base/auth.js +11 -11
  11. package/lib/axios/cjs/base/auth.js.map +1 -1
  12. package/lib/axios/cjs/base/keypair.js +1 -1
  13. package/lib/axios/cjs/base/keypair.js.map +1 -1
  14. package/lib/axios/cjs/base/transaction_builder.js +13 -1
  15. package/lib/axios/cjs/base/transaction_builder.js.map +1 -1
  16. package/lib/axios/cjs/bindings/config.js +1 -1
  17. package/lib/axios/cjs/bindings/config.js.map +1 -1
  18. package/lib/axios/cjs/bindings/wasm_fetcher.js +1 -1
  19. package/lib/axios/cjs/bindings/wasm_fetcher.js.map +1 -1
  20. package/lib/axios/cjs/contract/client.js.map +1 -1
  21. package/lib/axios/cjs/contract/spec.js.map +1 -1
  22. package/lib/axios/cjs/contract/types.js.map +1 -1
  23. package/lib/axios/cjs/contract/utils.js.map +1 -1
  24. package/lib/axios/cjs/contract/wasm_spec_parser.js +1 -1
  25. package/lib/axios/cjs/contract/wasm_spec_parser.js.map +1 -1
  26. package/lib/axios/cjs/horizon/call_builder.js.map +1 -1
  27. package/lib/axios/cjs/horizon/horizon_api.js.map +1 -1
  28. package/lib/axios/cjs/horizon/horizon_axios_client.js +1 -1
  29. package/lib/axios/cjs/horizon/horizon_axios_client.js.map +1 -1
  30. package/lib/axios/cjs/http-client/fetch-client.js +1 -1
  31. package/lib/axios/cjs/http-client/fetch-client.js.map +1 -1
  32. package/lib/axios/cjs/http-client/types.js.map +1 -1
  33. package/lib/axios/cjs/rpc/axios.js +1 -1
  34. package/lib/axios/cjs/rpc/axios.js.map +1 -1
  35. package/lib/axios/cjs/rpc/jsonrpc.js.map +1 -1
  36. package/lib/axios/cjs/rpc/server.js +2 -2
  37. package/lib/axios/cjs/rpc/server.js.map +1 -1
  38. package/lib/axios/cjs/webauth/challenge_transaction.js.map +1 -1
  39. package/lib/axios/esm/base/auth.d.ts +19 -7
  40. package/lib/axios/esm/base/auth.js +11 -11
  41. package/lib/axios/esm/base/auth.js.map +1 -1
  42. package/lib/axios/esm/base/keypair.js +1 -1
  43. package/lib/axios/esm/base/keypair.js.map +1 -1
  44. package/lib/axios/esm/base/transaction_builder.js +13 -1
  45. package/lib/axios/esm/base/transaction_builder.js.map +1 -1
  46. package/lib/axios/esm/bindings/config.js +1 -1
  47. package/lib/axios/esm/bindings/config.js.map +1 -1
  48. package/lib/axios/esm/bindings/wasm_fetcher.js +1 -1
  49. package/lib/axios/esm/bindings/wasm_fetcher.js.map +1 -1
  50. package/lib/axios/esm/contract/client.js.map +1 -1
  51. package/lib/axios/esm/contract/spec.js.map +1 -1
  52. package/lib/axios/esm/contract/types.js.map +1 -1
  53. package/lib/axios/esm/contract/utils.js.map +1 -1
  54. package/lib/axios/esm/contract/wasm_spec_parser.js +1 -1
  55. package/lib/axios/esm/contract/wasm_spec_parser.js.map +1 -1
  56. package/lib/axios/esm/horizon/call_builder.js.map +1 -1
  57. package/lib/axios/esm/horizon/horizon_api.js.map +1 -1
  58. package/lib/axios/esm/horizon/horizon_axios_client.js +1 -1
  59. package/lib/axios/esm/horizon/horizon_axios_client.js.map +1 -1
  60. package/lib/axios/esm/http-client/fetch-client.js +1 -1
  61. package/lib/axios/esm/http-client/fetch-client.js.map +1 -1
  62. package/lib/axios/esm/http-client/types.js.map +1 -1
  63. package/lib/axios/esm/rpc/axios.js +1 -1
  64. package/lib/axios/esm/rpc/axios.js.map +1 -1
  65. package/lib/axios/esm/rpc/jsonrpc.js.map +1 -1
  66. package/lib/axios/esm/rpc/server.js +2 -2
  67. package/lib/axios/esm/rpc/server.js.map +1 -1
  68. package/lib/axios/esm/webauth/challenge_transaction.js.map +1 -1
  69. package/lib/cjs/base/auth.js +11 -11
  70. package/lib/cjs/base/auth.js.map +1 -1
  71. package/lib/cjs/base/keypair.js +1 -1
  72. package/lib/cjs/base/keypair.js.map +1 -1
  73. package/lib/cjs/base/transaction_builder.js +13 -1
  74. package/lib/cjs/base/transaction_builder.js.map +1 -1
  75. package/lib/cjs/bindings/config.js +1 -1
  76. package/lib/cjs/bindings/config.js.map +1 -1
  77. package/lib/cjs/bindings/wasm_fetcher.js +1 -1
  78. package/lib/cjs/bindings/wasm_fetcher.js.map +1 -1
  79. package/lib/cjs/contract/client.js.map +1 -1
  80. package/lib/cjs/contract/spec.js.map +1 -1
  81. package/lib/cjs/contract/types.js.map +1 -1
  82. package/lib/cjs/contract/utils.js.map +1 -1
  83. package/lib/cjs/contract/wasm_spec_parser.js +1 -1
  84. package/lib/cjs/contract/wasm_spec_parser.js.map +1 -1
  85. package/lib/cjs/horizon/call_builder.js.map +1 -1
  86. package/lib/cjs/horizon/horizon_api.js.map +1 -1
  87. package/lib/cjs/horizon/horizon_axios_client.js +1 -1
  88. package/lib/cjs/horizon/horizon_axios_client.js.map +1 -1
  89. package/lib/cjs/http-client/fetch-client.js +1 -1
  90. package/lib/cjs/http-client/fetch-client.js.map +1 -1
  91. package/lib/cjs/http-client/types.js.map +1 -1
  92. package/lib/cjs/rpc/axios.js +1 -1
  93. package/lib/cjs/rpc/axios.js.map +1 -1
  94. package/lib/cjs/rpc/jsonrpc.js.map +1 -1
  95. package/lib/cjs/rpc/server.js +2 -2
  96. package/lib/cjs/rpc/server.js.map +1 -1
  97. package/lib/cjs/webauth/challenge_transaction.js.map +1 -1
  98. package/lib/esm/base/auth.d.ts +19 -7
  99. package/lib/esm/base/auth.js +11 -11
  100. package/lib/esm/base/auth.js.map +1 -1
  101. package/lib/esm/base/keypair.js +1 -1
  102. package/lib/esm/base/keypair.js.map +1 -1
  103. package/lib/esm/base/transaction_builder.js +13 -1
  104. package/lib/esm/base/transaction_builder.js.map +1 -1
  105. package/lib/esm/bindings/config.js +1 -1
  106. package/lib/esm/bindings/config.js.map +1 -1
  107. package/lib/esm/bindings/wasm_fetcher.js +1 -1
  108. package/lib/esm/bindings/wasm_fetcher.js.map +1 -1
  109. package/lib/esm/contract/client.js.map +1 -1
  110. package/lib/esm/contract/spec.js.map +1 -1
  111. package/lib/esm/contract/types.js.map +1 -1
  112. package/lib/esm/contract/utils.js.map +1 -1
  113. package/lib/esm/contract/wasm_spec_parser.js +1 -1
  114. package/lib/esm/contract/wasm_spec_parser.js.map +1 -1
  115. package/lib/esm/horizon/call_builder.js.map +1 -1
  116. package/lib/esm/horizon/horizon_api.js.map +1 -1
  117. package/lib/esm/horizon/horizon_axios_client.js +1 -1
  118. package/lib/esm/horizon/horizon_axios_client.js.map +1 -1
  119. package/lib/esm/http-client/fetch-client.js +1 -1
  120. package/lib/esm/http-client/fetch-client.js.map +1 -1
  121. package/lib/esm/http-client/types.js.map +1 -1
  122. package/lib/esm/rpc/axios.js +1 -1
  123. package/lib/esm/rpc/axios.js.map +1 -1
  124. package/lib/esm/rpc/jsonrpc.js.map +1 -1
  125. package/lib/esm/rpc/server.js +2 -2
  126. package/lib/esm/rpc/server.js.map +1 -1
  127. package/lib/esm/webauth/challenge_transaction.js.map +1 -1
  128. package/package.json +2 -5
@@ -1 +1 @@
1
- {"version":3,"file":"challenge_transaction.js","sources":["../../../src/webauth/challenge_transaction.ts"],"sourcesContent":["import {\n Keypair,\n Account,\n TransactionBuilder,\n BASE_FEE,\n Operation,\n Memo,\n MemoNone,\n MemoID,\n FeeBumpTransaction,\n TimeoutInfinite,\n Transaction,\n Networks,\n} from \"../base/index.js\";\nimport { InvalidChallengeError } from \"./errors.js\";\nimport { gatherTxSigners, verifyTxSignedBy } from \"./utils.js\";\nimport { Utils } from \"../utils.js\";\nimport { ServerApi } from \"../horizon/server_api.js\";\nimport { uint8ArrayToBase64 } from \"uint8array-extras\";\n\n/**\n * Returns a valid {@link https://stellar.org/protocol/sep-10 | SEP-10}\n * challenge transaction which you can use for Stellar Web Authentication.\n * @param serverKeypair - Keypair for server's signing account.\n * @param clientAccountID - The stellar account (G...) or muxed account\n * (M...) that the wallet wishes to authenticate with the server.\n * @param homeDomain - The fully qualified domain name of the service\n * requiring authentication\n * @param timeout - Challenge duration (default to 5 minutes).\n * @param networkPassphrase - The network passphrase. If you pass this\n * argument then timeout is required.\n * @param webAuthDomain - The fully qualified domain name of the service\n * issuing the challenge.\n * @param memo - The memo to attach to the challenge transaction. The\n * memo must be of type `id`. If the `clientaccountID` is a muxed account,\n * memos cannot be used.\n * @param clientDomain - The fully qualified domain of the client\n * requesting the challenge. Only necessary when the 'client_domain'\n * parameter is passed.\n * @param clientSigningKey - The public key assigned to the SIGNING_KEY\n * attribute specified on the stellar.toml hosted on the client domain. Only\n * necessary when the 'client_domain' parameter is passed.\n * @returns A base64 encoded string of the raw TransactionEnvelope xdr\n * struct for the transaction.\n * @throws Will throw if `clientAccountID` is a muxed account, and `memo`\n * is present.\n * @throws Will throw if `clientDomain` is provided, but\n * `clientSigningKey` is missing\n * @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}\n * @example\n * ```ts\n * import { Keypair, Networks, WebAuth } from 'stellar-sdk'\n *\n * let serverKeyPair = Keypair.fromSecret(\"server-secret\")\n * let challenge = WebAuth.buildChallengeTx(\n * serverKeyPair,\n * \"client-stellar-account-id\",\n * \"stellar.org\",\n * 300,\n * Networks.TESTNET);\n * ```\n */\nexport function buildChallengeTx(\n serverKeypair: Keypair,\n clientAccountID: string,\n homeDomain: string,\n // eslint-disable-next-line @typescript-eslint/default-param-last\n timeout: number = 300,\n networkPassphrase: string,\n webAuthDomain: string,\n memo: string | null = null,\n clientDomain: string | null = null,\n clientSigningKey: string | null = null,\n): string {\n if (clientAccountID.startsWith(\"M\") && memo) {\n throw Error(\"memo cannot be used if clientAccountID is a muxed account\");\n }\n\n const account = new Account(serverKeypair.publicKey(), \"-1\");\n const now = Math.floor(Date.now() / 1000);\n\n // A Base64 digit represents 6 bits, to generate a random 64 bytes\n // base64 string, we need 48 random bytes = (64 * 6)/8\n //\n // Each Base64 digit is in ASCII and each ASCII characters when\n // turned into binary represents 8 bits = 1 bytes.\n const value = uint8ArrayToBase64(crypto.getRandomValues(new Uint8Array(48)));\n\n const builder = new TransactionBuilder(account, {\n fee: BASE_FEE,\n networkPassphrase,\n timebounds: {\n minTime: now,\n maxTime: now + timeout,\n },\n })\n .addOperation(\n Operation.manageData({\n name: `${homeDomain} auth`,\n value,\n source: clientAccountID,\n }),\n )\n .addOperation(\n Operation.manageData({\n name: \"web_auth_domain\",\n value: webAuthDomain,\n source: account.accountId(),\n }),\n );\n\n if (clientDomain) {\n if (!clientSigningKey) {\n throw Error(\"clientSigningKey is required if clientDomain is provided\");\n }\n builder.addOperation(\n Operation.manageData({\n name: `client_domain`,\n value: clientDomain,\n source: clientSigningKey,\n }),\n );\n }\n\n if (memo) {\n builder.addMemo(Memo.id(memo));\n }\n\n const transaction = builder.build();\n transaction.sign(serverKeypair);\n\n return transaction.toEnvelope().toXDR(\"base64\").toString();\n}\n\n/**\n * Reads a SEP-10 challenge transaction and returns the decoded transaction and\n * client account ID contained within.\n *\n * It also verifies that the transaction has been signed by the server.\n *\n * It does not verify that the transaction has been signed by the client or that\n * any signatures other than the server's on the transaction are valid. Use one\n * of the following functions to completely verify the transaction:\n *\n * - {@link WebAuth.verifyChallengeTxThreshold}\n * - {@link WebAuth.verifyChallengeTxSigners}\n * @param challengeTx - SEP0010 challenge transaction in base64.\n * @param serverAccountID - The server's stellar account (public key).\n * @param networkPassphrase - The network passphrase, e.g.: 'Test SDF\n * Network ; September 2015' (see {@link Networks})\n * @param homeDomains - The home domain that is expected\n * to be included in the first Manage Data operation's string key. If an\n * array is provided, one of the domain names in the array must match.\n * @param webAuthDomain - The home domain that is expected to be included\n * as the value of the Manage Data operation with the 'web_auth_domain' key.\n * If no such operation is included, this parameter is not used.\n * @returns The actual transaction and the\n * Stellar public key (master key) used to sign the Manage Data operation,\n * the matched home domain, and the memo attached to the transaction, which\n * will be null if not present.\n * @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}\n */\nexport function readChallengeTx(\n challengeTx: string,\n serverAccountID: string,\n networkPassphrase: string,\n homeDomains: string | string[],\n webAuthDomain: string,\n): {\n tx: Transaction;\n clientAccountID: string;\n matchedHomeDomain: string;\n memo: string | null;\n} {\n if (serverAccountID.startsWith(\"M\")) {\n throw Error(\n \"Invalid serverAccountID: multiplexed accounts are not supported.\",\n );\n }\n\n let transaction;\n try {\n transaction = new Transaction(challengeTx, networkPassphrase);\n } catch {\n try {\n transaction = new FeeBumpTransaction(challengeTx, networkPassphrase);\n } catch {\n throw new InvalidChallengeError(\n \"Invalid challenge: unable to deserialize challengeTx transaction string\",\n );\n }\n throw new InvalidChallengeError(\n \"Invalid challenge: expected a Transaction but received a FeeBumpTransaction\",\n );\n }\n\n // verify sequence number\n const sequence = Number.parseInt(transaction.sequence, 10);\n\n if (sequence !== 0) {\n throw new InvalidChallengeError(\n \"The transaction sequence number should be zero\",\n );\n }\n\n // verify transaction source\n if (transaction.source !== serverAccountID) {\n throw new InvalidChallengeError(\n \"The transaction source account is not equal to the server's account\",\n );\n }\n\n // verify operation\n if (transaction.operations.length < 1) {\n throw new InvalidChallengeError(\n \"The transaction should contain at least one operation\",\n );\n }\n\n const [operation, ...subsequentOperations] = transaction.operations;\n\n if (!operation.source) {\n throw new InvalidChallengeError(\n \"The transaction's operation should contain a source account\",\n );\n }\n const clientAccountID: string = operation.source!;\n\n let memo: string | null = null;\n if (transaction.memo.type !== MemoNone) {\n if (clientAccountID.startsWith(\"M\")) {\n throw new InvalidChallengeError(\n \"The transaction has a memo but the client account ID is a muxed account\",\n );\n }\n if (transaction.memo.type !== MemoID) {\n throw new InvalidChallengeError(\n \"The transaction's memo must be of type `id`\",\n );\n }\n memo = transaction.memo.value as string;\n }\n\n if (operation.type !== \"manageData\") {\n throw new InvalidChallengeError(\n \"The transaction's operation type should be 'manageData'\",\n );\n }\n\n // verify timebounds\n if (\n transaction.timeBounds &&\n Number.parseInt(transaction.timeBounds?.maxTime, 10) === TimeoutInfinite\n ) {\n throw new InvalidChallengeError(\n \"The transaction requires non-infinite timebounds\",\n );\n }\n\n // give a small grace period for the transaction time to account for clock drift\n if (!Utils.validateTimebounds(transaction, 60 * 5)) {\n throw new InvalidChallengeError(\"The transaction has expired\");\n }\n\n if (operation.value === undefined) {\n throw new InvalidChallengeError(\n \"The transaction's operation values should not be null\",\n );\n }\n\n // verify base64\n if (!operation.value) {\n throw new InvalidChallengeError(\n \"The transaction's operation value should not be null\",\n );\n }\n\n if (Buffer.from(operation.value.toString(), \"base64\").length !== 48) {\n throw new InvalidChallengeError(\n \"The transaction's operation value should be a 64 bytes base64 random string\",\n );\n }\n\n // verify homeDomains\n if (!homeDomains) {\n throw new InvalidChallengeError(\n \"Invalid homeDomains: a home domain must be provided for verification\",\n );\n }\n\n let matchedHomeDomain;\n\n if (typeof homeDomains === \"string\") {\n if (`${homeDomains} auth` === operation.name) {\n matchedHomeDomain = homeDomains;\n }\n } else if (Array.isArray(homeDomains)) {\n matchedHomeDomain = homeDomains.find(\n (domain) => `${domain} auth` === operation.name,\n );\n } else {\n throw new InvalidChallengeError(\n `Invalid homeDomains: homeDomains type is ${typeof homeDomains} but should be a string or an array`,\n );\n }\n\n if (!matchedHomeDomain) {\n throw new InvalidChallengeError(\n \"Invalid homeDomains: the transaction's operation key name does not match the expected home domain\",\n );\n }\n\n // verify any subsequent operations are manage data ops and source account is the server\n for (const op of subsequentOperations) {\n if (op.type !== \"manageData\") {\n throw new InvalidChallengeError(\n \"The transaction has operations that are not of type 'manageData'\",\n );\n }\n if (op.source !== serverAccountID && op.name !== \"client_domain\") {\n throw new InvalidChallengeError(\n \"The transaction has operations that are unrecognized\",\n );\n }\n if (op.name === \"web_auth_domain\") {\n if (op.value === undefined) {\n throw new InvalidChallengeError(\n \"'web_auth_domain' operation value should not be null\",\n );\n }\n if (op.value.compare(Buffer.from(webAuthDomain))) {\n throw new InvalidChallengeError(\n `'web_auth_domain' operation value does not match ${webAuthDomain}`,\n );\n }\n }\n }\n\n if (!verifyTxSignedBy(transaction, serverAccountID)) {\n throw new InvalidChallengeError(\n `Transaction not signed by server: '${serverAccountID}'`,\n );\n }\n\n return { tx: transaction, clientAccountID, matchedHomeDomain, memo };\n}\n\n/**\n * Verifies that for a SEP 10 challenge transaction all signatures on the\n * transaction are accounted for. A transaction is verified if it is signed by\n * the server account, and all other signatures match a signer that has been\n * provided as an argument (as the accountIDs list). Additional signers can be\n * provided that do not have a signature, but all signatures must be matched to\n * a signer (accountIDs) for verification to succeed. If verification succeeds,\n * a list of signers that were found is returned, not including the server\n * account ID.\n *\n * Signers that are not prefixed as an address/account ID strkey (G...) will be\n * ignored.\n *\n * Errors will be raised if:\n * - The transaction is invalid according to\n * {@link WebAuth.readChallengeTx}.\n * - No client signatures are found on the transaction.\n * - One or more signatures in the transaction are not identifiable as the\n * server account or one of the signers provided in the arguments.\n * @param challengeTx - SEP0010 challenge transaction in base64.\n * @param serverAccountID - The server's stellar account (public key).\n * @param networkPassphrase - The network passphrase, e.g.: 'Test SDF\n * Network ; September 2015' (see {@link Networks}).\n * @param signers - The signers public keys. This list should\n * contain the public keys for all signers that have signed the transaction.\n * @param homeDomains - The home domain(s) that should\n * be included in the first Manage Data operation's string key. Required in\n * readChallengeTx().\n * @param webAuthDomain - The home domain that is expected to be included\n * as the value of the Manage Data operation with the 'web_auth_domain' key,\n * if present. Used in readChallengeTx().\n * @returns The list of signers public keys that have signed\n * the transaction, excluding the server account ID.\n * @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}\n * @example\n * ```ts\n * import { Networks, TransactionBuilder, WebAuth } from 'stellar-sdk';\n *\n * const serverKP = Keypair.random();\n * const clientKP1 = Keypair.random();\n * const clientKP2 = Keypair.random();\n *\n * // Challenge, possibly built in the server side\n * const challenge = WebAuth.buildChallengeTx(\n * serverKP,\n * clientKP1.publicKey(),\n * \"SDF\",\n * 300,\n * Networks.TESTNET\n * );\n *\n * // clock.tick(200); // Simulates a 200 ms delay when communicating from server to client\n *\n * // Transaction gathered from a challenge, possibly from the client side\n * const transaction = TransactionBuilder.fromXDR(challenge, Networks.TESTNET);\n * transaction.sign(clientKP1, clientKP2);\n * const signedChallenge = transaction\n * .toEnvelope()\n * .toXDR(\"base64\")\n * .toString();\n *\n * // The result below should be equal to [clientKP1.publicKey(), clientKP2.publicKey()]\n * WebAuth.verifyChallengeTxSigners(\n * signedChallenge,\n * serverKP.publicKey(),\n * Networks.TESTNET,\n * threshold,\n * [clientKP1.publicKey(), clientKP2.publicKey()]\n * );\n * ```\n */\nexport function verifyChallengeTxSigners(\n challengeTx: string,\n serverAccountID: string,\n networkPassphrase: string,\n signers: string[],\n homeDomains: string | string[],\n webAuthDomain: string,\n): string[] {\n // Read the transaction which validates its structure.\n const { tx } = readChallengeTx(\n challengeTx,\n serverAccountID,\n networkPassphrase,\n homeDomains,\n webAuthDomain,\n );\n\n // Ensure the server account ID is an address and not a seed.\n let serverKP: Keypair;\n try {\n serverKP = Keypair.fromPublicKey(serverAccountID); // can throw 'Invalid Stellar public key'\n } catch (err: any) {\n throw new Error(\n `Couldn't infer keypair from the provided 'serverAccountID': ${\n err.message\n }`,\n );\n }\n\n // Deduplicate the client signers and ensure the server is not included\n // anywhere we check or output the list of signers.\n const clientSigners = new Set<string>();\n for (const signer of signers) {\n // Ignore the server signer if it is in the signers list. It's\n // important when verifying signers of a challenge transaction that we\n // only verify and return client signers. If an account has the server\n // as a signer the server should not play a part in the authentication\n // of the client.\n if (signer === serverKP.publicKey()) {\n continue;\n }\n\n // Ignore non-G... account/address signers.\n if (signer.charAt(0) !== \"G\") {\n continue;\n }\n\n clientSigners.add(signer);\n }\n\n // Don't continue if none of the signers provided are in the final list.\n if (clientSigners.size === 0) {\n throw new InvalidChallengeError(\n \"No verifiable client signers provided, at least one G... address must be provided\",\n );\n }\n\n let clientSigningKey;\n for (const op of tx.operations) {\n if (op.type === \"manageData\" && op.name === \"client_domain\") {\n if (clientSigningKey) {\n throw new InvalidChallengeError(\n \"Found more than one client_domain operation\",\n );\n }\n clientSigningKey = op.source;\n }\n }\n\n // Verify all the transaction's signers (server and client) in one\n // hit. We do this in one hit here even though the server signature was\n // checked in the ReadChallengeTx to ensure that every signature and signer\n // are consumed only once on the transaction.\n const allSigners: string[] = [\n serverKP.publicKey(),\n ...Array.from(clientSigners),\n ];\n if (clientSigningKey) {\n allSigners.push(clientSigningKey);\n }\n\n const signersFound: string[] = gatherTxSigners(tx, allSigners);\n\n let serverSignatureFound = false;\n let clientSigningKeySignatureFound = false;\n for (const signer of signersFound) {\n if (signer === serverKP.publicKey()) {\n serverSignatureFound = true;\n }\n if (signer === clientSigningKey) {\n clientSigningKeySignatureFound = true;\n }\n }\n\n // Confirm we matched a signature to the server signer.\n if (!serverSignatureFound) {\n throw new InvalidChallengeError(\n `Transaction not signed by server: '${serverKP.publicKey()}'`,\n );\n }\n\n // Confirm we matched a signature to the client domain's signer\n if (clientSigningKey && !clientSigningKeySignatureFound) {\n throw new InvalidChallengeError(\n \"Transaction not signed by the source account of the 'client_domain' \" +\n \"ManageData operation\",\n );\n }\n\n // Confirm we matched at least one given signer with the transaction signatures\n if (signersFound.length === 1) {\n throw new InvalidChallengeError(\n \"None of the given signers match the transaction signatures\",\n );\n }\n\n // Confirm all signatures, including the server signature, were consumed by a signer:\n if (signersFound.length !== tx.signatures.length) {\n throw new InvalidChallengeError(\"Transaction has unrecognized signatures\");\n }\n\n // Remove the server public key before returning\n signersFound.splice(signersFound.indexOf(serverKP.publicKey()), 1);\n if (clientSigningKey) {\n // Remove the client domain public key public key before returning\n signersFound.splice(signersFound.indexOf(clientSigningKey), 1);\n }\n\n if (signersFound.length === 0) {\n throw new InvalidChallengeError(\n \"None of the given signers match the transaction signatures\",\n );\n }\n\n return signersFound;\n}\n\n/**\n * Verifies that for a SEP-10 challenge transaction all signatures on the\n * transaction are accounted for and that the signatures meet a threshold on an\n * account. A transaction is verified if it is signed by the server account, and\n * all other signatures match a signer that has been provided as an argument,\n * and those signatures meet a threshold on the account.\n *\n * Signers that are not prefixed as an address/account ID strkey (G...) will be\n * ignored.\n *\n * Errors will be raised if:\n * - The transaction is invalid according to\n * {@link WebAuth.readChallengeTx}.\n * - No client signatures are found on the transaction.\n * - One or more signatures in the transaction are not identifiable as the\n * server account or one of the signers provided in the arguments.\n * - The signatures are all valid but do not meet the threshold.\n * @param challengeTx - SEP0010 challenge transaction in base64.\n * @param serverAccountID - The server's stellar account (public key).\n * @param networkPassphrase - The network passphrase, e.g.: 'Test SDF\n * Network ; September 2015' (see {@link Networks}).\n * @param threshold - The required signatures threshold for verifying\n * this transaction.\n * @param signerSummary - a map of all\n * authorized signers to their weights. It's used to validate if the\n * transaction signatures have met the given threshold.\n * @param homeDomains - The home domain(s) that should\n * be included in the first Manage Data operation's string key. Required in\n * `verifyChallengeTxSigners() => readChallengeTx()`.\n * @param webAuthDomain - The home domain that is expected to be included\n * as the value of the Manage Data operation with the 'web_auth_domain' key,\n * if present. Used in `verifyChallengeTxSigners() => readChallengeTx()`.\n * @returns The list of signers public keys that have signed\n * the transaction, excluding the server account ID, given that the threshold\n * was met.\n * @throws Will throw if the collective\n * weight of the transaction's signers does not meet the necessary threshold\n * to verify this transaction.\n * @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}\n * @example\n * ```ts\n * import { Networks, TransactionBuilder, WebAuth } from 'stellar-sdk';\n *\n * const serverKP = Keypair.random();\n * const clientKP1 = Keypair.random();\n * const clientKP2 = Keypair.random();\n *\n * // Challenge, possibly built in the server side\n * const challenge = WebAuth.buildChallengeTx(\n * serverKP,\n * clientKP1.publicKey(),\n * \"SDF\",\n * 300,\n * Networks.TESTNET\n * );\n *\n * // clock.tick(200); // Simulates a 200 ms delay when communicating from server to client\n *\n * // Transaction gathered from a challenge, possibly from the client side\n * const transaction = TransactionBuilder.fromXDR(challenge, Networks.TESTNET);\n * transaction.sign(clientKP1, clientKP2);\n * const signedChallenge = transaction\n * .toEnvelope()\n * .toXDR(\"base64\")\n * .toString();\n *\n * // Defining the threshold and signerSummary\n * const threshold = 3;\n * const signerSummary = [\n * {\n * key: this.clientKP1.publicKey(),\n * weight: 1,\n * },\n * {\n * key: this.clientKP2.publicKey(),\n * weight: 2,\n * },\n * ];\n *\n * // The result below should be equal to [clientKP1.publicKey(), clientKP2.publicKey()]\n * WebAuth.verifyChallengeTxThreshold(\n * signedChallenge,\n * serverKP.publicKey(),\n * Networks.TESTNET,\n * threshold,\n * signerSummary\n * );\n * ```\n */\nexport function verifyChallengeTxThreshold(\n challengeTx: string,\n serverAccountID: string,\n networkPassphrase: string,\n threshold: number,\n signerSummary: ServerApi.AccountRecordSigners[],\n homeDomains: string | string[],\n webAuthDomain: string,\n): string[] {\n const signers = signerSummary.map((signer) => signer.key);\n\n const signersFound = verifyChallengeTxSigners(\n challengeTx,\n serverAccountID,\n networkPassphrase,\n signers,\n homeDomains,\n webAuthDomain,\n );\n\n let weight = 0;\n for (const signer of signersFound) {\n const sigWeight = signerSummary.find((s) => s.key === signer)?.weight || 0;\n weight += sigWeight;\n }\n\n if (weight < threshold) {\n throw new InvalidChallengeError(\n `signers with weight ${weight} do not meet threshold ${threshold}\"`,\n );\n }\n\n return signersFound;\n}\n"],"names":["memo","account","Account","uint8ArrayToBase64","TransactionBuilder","BASE_FEE","Operation","Memo","transaction","Transaction","FeeBumpTransaction","InvalidChallengeError","MemoNone","MemoID","TimeoutInfinite","Utils","Buffer","verifyTxSignedBy","Keypair","gatherTxSigners"],"mappings":"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"}
1
+ {"version":3,"file":"challenge_transaction.js","sources":["../../../src/webauth/challenge_transaction.ts"],"sourcesContent":["import {\n Keypair,\n Account,\n TransactionBuilder,\n BASE_FEE,\n Operation,\n Memo,\n MemoNone,\n MemoID,\n FeeBumpTransaction,\n TimeoutInfinite,\n Transaction,\n Networks,\n} from \"../base/index.js\";\nimport { InvalidChallengeError } from \"./errors.js\";\nimport { gatherTxSigners, verifyTxSignedBy } from \"./utils.js\";\nimport { Utils } from \"../utils.js\";\nimport { ServerApi } from \"../horizon/server_api.js\";\nimport { uint8ArrayToBase64 } from \"uint8array-extras\";\n\n/**\n * Returns a valid {@link https://stellar.org/protocol/sep-10 | SEP-10}\n * challenge transaction which you can use for Stellar Web Authentication.\n * @param serverKeypair - Keypair for server's signing account.\n * @param clientAccountID - The stellar account (G...) or muxed account\n * (M...) that the wallet wishes to authenticate with the server.\n * @param homeDomain - The fully qualified domain name of the service\n * requiring authentication\n * @param timeout - Challenge duration (default to 5 minutes).\n * @param networkPassphrase - The network passphrase. If you pass this\n * argument then timeout is required.\n * @param webAuthDomain - The fully qualified domain name of the service\n * issuing the challenge.\n * @param memo - The memo to attach to the challenge transaction. The\n * memo must be of type `id`. If the `clientaccountID` is a muxed account,\n * memos cannot be used.\n * @param clientDomain - The fully qualified domain of the client\n * requesting the challenge. Only necessary when the 'client_domain'\n * parameter is passed.\n * @param clientSigningKey - The public key assigned to the SIGNING_KEY\n * attribute specified on the stellar.toml hosted on the client domain. Only\n * necessary when the 'client_domain' parameter is passed.\n * @returns A base64 encoded string of the raw TransactionEnvelope xdr\n * struct for the transaction.\n * @throws Will throw if `clientAccountID` is a muxed account, and `memo`\n * is present.\n * @throws Will throw if `clientDomain` is provided, but\n * `clientSigningKey` is missing\n * @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}\n * @example\n * ```ts\n * import { Keypair, Networks, WebAuth } from 'stellar-sdk'\n *\n * let serverKeyPair = Keypair.fromSecret(\"server-secret\")\n * let challenge = WebAuth.buildChallengeTx(\n * serverKeyPair,\n * \"client-stellar-account-id\",\n * \"stellar.org\",\n * 300,\n * Networks.TESTNET);\n * ```\n */\nexport function buildChallengeTx(\n serverKeypair: Keypair,\n clientAccountID: string,\n homeDomain: string,\n\n timeout: number = 300,\n networkPassphrase: string,\n webAuthDomain: string,\n memo: string | null = null,\n clientDomain: string | null = null,\n clientSigningKey: string | null = null,\n): string {\n if (clientAccountID.startsWith(\"M\") && memo) {\n throw Error(\"memo cannot be used if clientAccountID is a muxed account\");\n }\n\n const account = new Account(serverKeypair.publicKey(), \"-1\");\n const now = Math.floor(Date.now() / 1000);\n\n // A Base64 digit represents 6 bits, to generate a random 64 bytes\n // base64 string, we need 48 random bytes = (64 * 6)/8\n //\n // Each Base64 digit is in ASCII and each ASCII characters when\n // turned into binary represents 8 bits = 1 bytes.\n const value = uint8ArrayToBase64(crypto.getRandomValues(new Uint8Array(48)));\n\n const builder = new TransactionBuilder(account, {\n fee: BASE_FEE,\n networkPassphrase,\n timebounds: {\n minTime: now,\n maxTime: now + timeout,\n },\n })\n .addOperation(\n Operation.manageData({\n name: `${homeDomain} auth`,\n value,\n source: clientAccountID,\n }),\n )\n .addOperation(\n Operation.manageData({\n name: \"web_auth_domain\",\n value: webAuthDomain,\n source: account.accountId(),\n }),\n );\n\n if (clientDomain) {\n if (!clientSigningKey) {\n throw Error(\"clientSigningKey is required if clientDomain is provided\");\n }\n builder.addOperation(\n Operation.manageData({\n name: `client_domain`,\n value: clientDomain,\n source: clientSigningKey,\n }),\n );\n }\n\n if (memo) {\n builder.addMemo(Memo.id(memo));\n }\n\n const transaction = builder.build();\n transaction.sign(serverKeypair);\n\n return transaction.toEnvelope().toXDR(\"base64\").toString();\n}\n\n/**\n * Reads a SEP-10 challenge transaction and returns the decoded transaction and\n * client account ID contained within.\n *\n * It also verifies that the transaction has been signed by the server.\n *\n * It does not verify that the transaction has been signed by the client or that\n * any signatures other than the server's on the transaction are valid. Use one\n * of the following functions to completely verify the transaction:\n *\n * - {@link WebAuth.verifyChallengeTxThreshold}\n * - {@link WebAuth.verifyChallengeTxSigners}\n * @param challengeTx - SEP0010 challenge transaction in base64.\n * @param serverAccountID - The server's stellar account (public key).\n * @param networkPassphrase - The network passphrase, e.g.: 'Test SDF\n * Network ; September 2015' (see {@link Networks})\n * @param homeDomains - The home domain that is expected\n * to be included in the first Manage Data operation's string key. If an\n * array is provided, one of the domain names in the array must match.\n * @param webAuthDomain - The home domain that is expected to be included\n * as the value of the Manage Data operation with the 'web_auth_domain' key.\n * If no such operation is included, this parameter is not used.\n * @returns The actual transaction and the\n * Stellar public key (master key) used to sign the Manage Data operation,\n * the matched home domain, and the memo attached to the transaction, which\n * will be null if not present.\n * @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}\n */\nexport function readChallengeTx(\n challengeTx: string,\n serverAccountID: string,\n networkPassphrase: string,\n homeDomains: string | string[],\n webAuthDomain: string,\n): {\n tx: Transaction;\n clientAccountID: string;\n matchedHomeDomain: string;\n memo: string | null;\n} {\n if (serverAccountID.startsWith(\"M\")) {\n throw Error(\n \"Invalid serverAccountID: multiplexed accounts are not supported.\",\n );\n }\n\n let transaction;\n try {\n transaction = new Transaction(challengeTx, networkPassphrase);\n } catch {\n try {\n transaction = new FeeBumpTransaction(challengeTx, networkPassphrase);\n } catch {\n throw new InvalidChallengeError(\n \"Invalid challenge: unable to deserialize challengeTx transaction string\",\n );\n }\n throw new InvalidChallengeError(\n \"Invalid challenge: expected a Transaction but received a FeeBumpTransaction\",\n );\n }\n\n // verify sequence number\n const sequence = Number.parseInt(transaction.sequence, 10);\n\n if (sequence !== 0) {\n throw new InvalidChallengeError(\n \"The transaction sequence number should be zero\",\n );\n }\n\n // verify transaction source\n if (transaction.source !== serverAccountID) {\n throw new InvalidChallengeError(\n \"The transaction source account is not equal to the server's account\",\n );\n }\n\n // verify operation\n if (transaction.operations.length < 1) {\n throw new InvalidChallengeError(\n \"The transaction should contain at least one operation\",\n );\n }\n\n const [operation, ...subsequentOperations] = transaction.operations;\n\n if (!operation.source) {\n throw new InvalidChallengeError(\n \"The transaction's operation should contain a source account\",\n );\n }\n const clientAccountID: string = operation.source!;\n\n let memo: string | null = null;\n if (transaction.memo.type !== MemoNone) {\n if (clientAccountID.startsWith(\"M\")) {\n throw new InvalidChallengeError(\n \"The transaction has a memo but the client account ID is a muxed account\",\n );\n }\n if (transaction.memo.type !== MemoID) {\n throw new InvalidChallengeError(\n \"The transaction's memo must be of type `id`\",\n );\n }\n memo = transaction.memo.value as string;\n }\n\n if (operation.type !== \"manageData\") {\n throw new InvalidChallengeError(\n \"The transaction's operation type should be 'manageData'\",\n );\n }\n\n // verify timebounds\n if (\n transaction.timeBounds &&\n Number.parseInt(transaction.timeBounds?.maxTime, 10) === TimeoutInfinite\n ) {\n throw new InvalidChallengeError(\n \"The transaction requires non-infinite timebounds\",\n );\n }\n\n // give a small grace period for the transaction time to account for clock drift\n if (!Utils.validateTimebounds(transaction, 60 * 5)) {\n throw new InvalidChallengeError(\"The transaction has expired\");\n }\n\n if (operation.value === undefined) {\n throw new InvalidChallengeError(\n \"The transaction's operation values should not be null\",\n );\n }\n\n // verify base64\n if (!operation.value) {\n throw new InvalidChallengeError(\n \"The transaction's operation value should not be null\",\n );\n }\n\n if (Buffer.from(operation.value.toString(), \"base64\").length !== 48) {\n throw new InvalidChallengeError(\n \"The transaction's operation value should be a 64 bytes base64 random string\",\n );\n }\n\n // verify homeDomains\n if (!homeDomains) {\n throw new InvalidChallengeError(\n \"Invalid homeDomains: a home domain must be provided for verification\",\n );\n }\n\n let matchedHomeDomain;\n\n if (typeof homeDomains === \"string\") {\n if (`${homeDomains} auth` === operation.name) {\n matchedHomeDomain = homeDomains;\n }\n } else if (Array.isArray(homeDomains)) {\n matchedHomeDomain = homeDomains.find(\n (domain) => `${domain} auth` === operation.name,\n );\n } else {\n throw new InvalidChallengeError(\n `Invalid homeDomains: homeDomains type is ${typeof homeDomains} but should be a string or an array`,\n );\n }\n\n if (!matchedHomeDomain) {\n throw new InvalidChallengeError(\n \"Invalid homeDomains: the transaction's operation key name does not match the expected home domain\",\n );\n }\n\n // verify any subsequent operations are manage data ops and source account is the server\n for (const op of subsequentOperations) {\n if (op.type !== \"manageData\") {\n throw new InvalidChallengeError(\n \"The transaction has operations that are not of type 'manageData'\",\n );\n }\n if (op.source !== serverAccountID && op.name !== \"client_domain\") {\n throw new InvalidChallengeError(\n \"The transaction has operations that are unrecognized\",\n );\n }\n if (op.name === \"web_auth_domain\") {\n if (op.value === undefined) {\n throw new InvalidChallengeError(\n \"'web_auth_domain' operation value should not be null\",\n );\n }\n if (op.value.compare(Buffer.from(webAuthDomain))) {\n throw new InvalidChallengeError(\n `'web_auth_domain' operation value does not match ${webAuthDomain}`,\n );\n }\n }\n }\n\n if (!verifyTxSignedBy(transaction, serverAccountID)) {\n throw new InvalidChallengeError(\n `Transaction not signed by server: '${serverAccountID}'`,\n );\n }\n\n return { tx: transaction, clientAccountID, matchedHomeDomain, memo };\n}\n\n/**\n * Verifies that for a SEP 10 challenge transaction all signatures on the\n * transaction are accounted for. A transaction is verified if it is signed by\n * the server account, and all other signatures match a signer that has been\n * provided as an argument (as the accountIDs list). Additional signers can be\n * provided that do not have a signature, but all signatures must be matched to\n * a signer (accountIDs) for verification to succeed. If verification succeeds,\n * a list of signers that were found is returned, not including the server\n * account ID.\n *\n * Signers that are not prefixed as an address/account ID strkey (G...) will be\n * ignored.\n *\n * Errors will be raised if:\n * - The transaction is invalid according to\n * {@link WebAuth.readChallengeTx}.\n * - No client signatures are found on the transaction.\n * - One or more signatures in the transaction are not identifiable as the\n * server account or one of the signers provided in the arguments.\n * @param challengeTx - SEP0010 challenge transaction in base64.\n * @param serverAccountID - The server's stellar account (public key).\n * @param networkPassphrase - The network passphrase, e.g.: 'Test SDF\n * Network ; September 2015' (see {@link Networks}).\n * @param signers - The signers public keys. This list should\n * contain the public keys for all signers that have signed the transaction.\n * @param homeDomains - The home domain(s) that should\n * be included in the first Manage Data operation's string key. Required in\n * readChallengeTx().\n * @param webAuthDomain - The home domain that is expected to be included\n * as the value of the Manage Data operation with the 'web_auth_domain' key,\n * if present. Used in readChallengeTx().\n * @returns The list of signers public keys that have signed\n * the transaction, excluding the server account ID.\n * @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}\n * @example\n * ```ts\n * import { Networks, TransactionBuilder, WebAuth } from 'stellar-sdk';\n *\n * const serverKP = Keypair.random();\n * const clientKP1 = Keypair.random();\n * const clientKP2 = Keypair.random();\n *\n * // Challenge, possibly built in the server side\n * const challenge = WebAuth.buildChallengeTx(\n * serverKP,\n * clientKP1.publicKey(),\n * \"SDF\",\n * 300,\n * Networks.TESTNET\n * );\n *\n * // clock.tick(200); // Simulates a 200 ms delay when communicating from server to client\n *\n * // Transaction gathered from a challenge, possibly from the client side\n * const transaction = TransactionBuilder.fromXDR(challenge, Networks.TESTNET);\n * transaction.sign(clientKP1, clientKP2);\n * const signedChallenge = transaction\n * .toEnvelope()\n * .toXDR(\"base64\")\n * .toString();\n *\n * // The result below should be equal to [clientKP1.publicKey(), clientKP2.publicKey()]\n * WebAuth.verifyChallengeTxSigners(\n * signedChallenge,\n * serverKP.publicKey(),\n * Networks.TESTNET,\n * threshold,\n * [clientKP1.publicKey(), clientKP2.publicKey()]\n * );\n * ```\n */\nexport function verifyChallengeTxSigners(\n challengeTx: string,\n serverAccountID: string,\n networkPassphrase: string,\n signers: string[],\n homeDomains: string | string[],\n webAuthDomain: string,\n): string[] {\n // Read the transaction which validates its structure.\n const { tx } = readChallengeTx(\n challengeTx,\n serverAccountID,\n networkPassphrase,\n homeDomains,\n webAuthDomain,\n );\n\n // Ensure the server account ID is an address and not a seed.\n let serverKP: Keypair;\n try {\n serverKP = Keypair.fromPublicKey(serverAccountID); // can throw 'Invalid Stellar public key'\n } catch (err: any) {\n throw new Error(\n `Couldn't infer keypair from the provided 'serverAccountID': ${\n err.message\n }`,\n );\n }\n\n // Deduplicate the client signers and ensure the server is not included\n // anywhere we check or output the list of signers.\n const clientSigners = new Set<string>();\n for (const signer of signers) {\n // Ignore the server signer if it is in the signers list. It's\n // important when verifying signers of a challenge transaction that we\n // only verify and return client signers. If an account has the server\n // as a signer the server should not play a part in the authentication\n // of the client.\n if (signer === serverKP.publicKey()) {\n continue;\n }\n\n // Ignore non-G... account/address signers.\n if (signer.charAt(0) !== \"G\") {\n continue;\n }\n\n clientSigners.add(signer);\n }\n\n // Don't continue if none of the signers provided are in the final list.\n if (clientSigners.size === 0) {\n throw new InvalidChallengeError(\n \"No verifiable client signers provided, at least one G... address must be provided\",\n );\n }\n\n let clientSigningKey;\n for (const op of tx.operations) {\n if (op.type === \"manageData\" && op.name === \"client_domain\") {\n if (clientSigningKey) {\n throw new InvalidChallengeError(\n \"Found more than one client_domain operation\",\n );\n }\n clientSigningKey = op.source;\n }\n }\n\n // Verify all the transaction's signers (server and client) in one\n // hit. We do this in one hit here even though the server signature was\n // checked in the ReadChallengeTx to ensure that every signature and signer\n // are consumed only once on the transaction.\n const allSigners: string[] = [\n serverKP.publicKey(),\n ...Array.from(clientSigners),\n ];\n if (clientSigningKey) {\n allSigners.push(clientSigningKey);\n }\n\n const signersFound: string[] = gatherTxSigners(tx, allSigners);\n\n let serverSignatureFound = false;\n let clientSigningKeySignatureFound = false;\n for (const signer of signersFound) {\n if (signer === serverKP.publicKey()) {\n serverSignatureFound = true;\n }\n if (signer === clientSigningKey) {\n clientSigningKeySignatureFound = true;\n }\n }\n\n // Confirm we matched a signature to the server signer.\n if (!serverSignatureFound) {\n throw new InvalidChallengeError(\n `Transaction not signed by server: '${serverKP.publicKey()}'`,\n );\n }\n\n // Confirm we matched a signature to the client domain's signer\n if (clientSigningKey && !clientSigningKeySignatureFound) {\n throw new InvalidChallengeError(\n \"Transaction not signed by the source account of the 'client_domain' \" +\n \"ManageData operation\",\n );\n }\n\n // Confirm we matched at least one given signer with the transaction signatures\n if (signersFound.length === 1) {\n throw new InvalidChallengeError(\n \"None of the given signers match the transaction signatures\",\n );\n }\n\n // Confirm all signatures, including the server signature, were consumed by a signer:\n if (signersFound.length !== tx.signatures.length) {\n throw new InvalidChallengeError(\"Transaction has unrecognized signatures\");\n }\n\n // Remove the server public key before returning\n signersFound.splice(signersFound.indexOf(serverKP.publicKey()), 1);\n if (clientSigningKey) {\n // Remove the client domain public key public key before returning\n signersFound.splice(signersFound.indexOf(clientSigningKey), 1);\n }\n\n if (signersFound.length === 0) {\n throw new InvalidChallengeError(\n \"None of the given signers match the transaction signatures\",\n );\n }\n\n return signersFound;\n}\n\n/**\n * Verifies that for a SEP-10 challenge transaction all signatures on the\n * transaction are accounted for and that the signatures meet a threshold on an\n * account. A transaction is verified if it is signed by the server account, and\n * all other signatures match a signer that has been provided as an argument,\n * and those signatures meet a threshold on the account.\n *\n * Signers that are not prefixed as an address/account ID strkey (G...) will be\n * ignored.\n *\n * Errors will be raised if:\n * - The transaction is invalid according to\n * {@link WebAuth.readChallengeTx}.\n * - No client signatures are found on the transaction.\n * - One or more signatures in the transaction are not identifiable as the\n * server account or one of the signers provided in the arguments.\n * - The signatures are all valid but do not meet the threshold.\n * @param challengeTx - SEP0010 challenge transaction in base64.\n * @param serverAccountID - The server's stellar account (public key).\n * @param networkPassphrase - The network passphrase, e.g.: 'Test SDF\n * Network ; September 2015' (see {@link Networks}).\n * @param threshold - The required signatures threshold for verifying\n * this transaction.\n * @param signerSummary - a map of all\n * authorized signers to their weights. It's used to validate if the\n * transaction signatures have met the given threshold.\n * @param homeDomains - The home domain(s) that should\n * be included in the first Manage Data operation's string key. Required in\n * `verifyChallengeTxSigners() => readChallengeTx()`.\n * @param webAuthDomain - The home domain that is expected to be included\n * as the value of the Manage Data operation with the 'web_auth_domain' key,\n * if present. Used in `verifyChallengeTxSigners() => readChallengeTx()`.\n * @returns The list of signers public keys that have signed\n * the transaction, excluding the server account ID, given that the threshold\n * was met.\n * @throws Will throw if the collective\n * weight of the transaction's signers does not meet the necessary threshold\n * to verify this transaction.\n * @see {@link https://stellar.org/protocol/sep-10 | SEP-10: Stellar Web Auth}\n * @example\n * ```ts\n * import { Networks, TransactionBuilder, WebAuth } from 'stellar-sdk';\n *\n * const serverKP = Keypair.random();\n * const clientKP1 = Keypair.random();\n * const clientKP2 = Keypair.random();\n *\n * // Challenge, possibly built in the server side\n * const challenge = WebAuth.buildChallengeTx(\n * serverKP,\n * clientKP1.publicKey(),\n * \"SDF\",\n * 300,\n * Networks.TESTNET\n * );\n *\n * // clock.tick(200); // Simulates a 200 ms delay when communicating from server to client\n *\n * // Transaction gathered from a challenge, possibly from the client side\n * const transaction = TransactionBuilder.fromXDR(challenge, Networks.TESTNET);\n * transaction.sign(clientKP1, clientKP2);\n * const signedChallenge = transaction\n * .toEnvelope()\n * .toXDR(\"base64\")\n * .toString();\n *\n * // Defining the threshold and signerSummary\n * const threshold = 3;\n * const signerSummary = [\n * {\n * key: this.clientKP1.publicKey(),\n * weight: 1,\n * },\n * {\n * key: this.clientKP2.publicKey(),\n * weight: 2,\n * },\n * ];\n *\n * // The result below should be equal to [clientKP1.publicKey(), clientKP2.publicKey()]\n * WebAuth.verifyChallengeTxThreshold(\n * signedChallenge,\n * serverKP.publicKey(),\n * Networks.TESTNET,\n * threshold,\n * signerSummary\n * );\n * ```\n */\nexport function verifyChallengeTxThreshold(\n challengeTx: string,\n serverAccountID: string,\n networkPassphrase: string,\n threshold: number,\n signerSummary: ServerApi.AccountRecordSigners[],\n homeDomains: string | string[],\n webAuthDomain: string,\n): string[] {\n const signers = signerSummary.map((signer) => signer.key);\n\n const signersFound = verifyChallengeTxSigners(\n challengeTx,\n serverAccountID,\n networkPassphrase,\n signers,\n homeDomains,\n webAuthDomain,\n );\n\n let weight = 0;\n for (const signer of signersFound) {\n const sigWeight = signerSummary.find((s) => s.key === signer)?.weight || 0;\n weight += sigWeight;\n }\n\n if (weight < threshold) {\n throw new InvalidChallengeError(\n `signers with weight ${weight} do not meet threshold ${threshold}\"`,\n );\n }\n\n return signersFound;\n}\n"],"names":["memo","account","Account","uint8ArrayToBase64","TransactionBuilder","BASE_FEE","Operation","Memo","transaction","Transaction","FeeBumpTransaction","InvalidChallengeError","MemoNone","MemoID","TimeoutInfinite","Utils","Buffer","verifyTxSignedBy","Keypair","gatherTxSigners"],"mappings":"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"}
@@ -115,6 +115,22 @@ export type SigningCallback = (preimage: xdr.HashIdPreimage) => Promise<BufferLi
115
115
  * ```
116
116
  */
117
117
  export declare function authorizeEntry(entry: xdr.SorobanAuthorizationEntry, signer: Keypair | SigningCallback, validUntilLedgerSeq: number, networkPassphrase: string, forAddress?: string): Promise<xdr.SorobanAuthorizationEntry>;
118
+ export interface AuthorizeInvocationParams {
119
+ signer: Keypair | SigningCallback;
120
+ validUntilLedgerSeq: number;
121
+ invocation: xdr.SorobanAuthorizedInvocation;
122
+ networkPassphrase: string;
123
+ publicKey?: string;
124
+ /**
125
+ * Build `SOROBAN_CREDENTIALS_ADDRESS_V2` (CAP-71) credentials instead of the
126
+ * legacy `SOROBAN_CREDENTIALS_ADDRESS`. V2 credentials bind the address into
127
+ * the signed payload but are only valid on networks that have activated
128
+ * CAP-71, so leave this off until the activation vote passes for your target
129
+ * network. The default flips to `true` once V2 becomes mandatory.
130
+ * @defaultValue false
131
+ */
132
+ authV2?: boolean;
133
+ }
118
134
  /**
119
135
  * This builds an entry from scratch, allowing you to express authorization as a
120
136
  * function of:
@@ -143,16 +159,12 @@ export declare function authorizeEntry(entry: xdr.SorobanAuthorizationEntry, sig
143
159
  * - `publicKey`: the public identity of the signer (when providing a
144
160
  * {@link Keypair} to `signer`, this can be omitted, as it just uses
145
161
  * {@link Keypair.publicKey})
162
+ * - `authV2`: build `SOROBAN_CREDENTIALS_ADDRESS_V2` (CAP-71) credentials
163
+ * rather than the legacy `SOROBAN_CREDENTIALS_ADDRESS`. Defaults to `false`;
164
+ * only enable it for networks that have activated CAP-71.
146
165
  *
147
166
  * @see authorizeEntry
148
167
  */
149
- export interface AuthorizeInvocationParams {
150
- signer: Keypair | SigningCallback;
151
- validUntilLedgerSeq: number;
152
- invocation: xdr.SorobanAuthorizedInvocation;
153
- networkPassphrase: string;
154
- publicKey?: string;
155
- }
156
168
  export declare function authorizeInvocation(params: AuthorizeInvocationParams): Promise<xdr.SorobanAuthorizationEntry>;
157
169
  /**
158
170
  * Builds the {@link xdr.HashIdPreimage} whose hash a signer must sign to
@@ -77,7 +77,8 @@ function authorizeInvocation(params) {
77
77
  validUntilLedgerSeq,
78
78
  invocation,
79
79
  networkPassphrase,
80
- publicKey = ""
80
+ publicKey = "",
81
+ authV2 = false
81
82
  } = params;
82
83
  const kp = Keypair.random().rawPublicKey();
83
84
  const nonce = new types.Int64(bytesToInt64(kp));
@@ -85,18 +86,17 @@ function authorizeInvocation(params) {
85
86
  if (!pk) {
86
87
  throw new Error(`authorizeInvocation requires publicKey parameter`);
87
88
  }
89
+ const addressCredentials = new types.SorobanAddressCredentials({
90
+ address: new Address(pk).toScAddress(),
91
+ nonce,
92
+ signatureExpirationLedger: 0,
93
+ // replaced
94
+ signature: types.ScVal.scvVec([])
95
+ // replaced
96
+ });
88
97
  const entry = new types.SorobanAuthorizationEntry({
89
98
  rootInvocation: invocation,
90
- credentials: types.SorobanCredentials.sorobanCredentialsAddressV2(
91
- new types.SorobanAddressCredentials({
92
- address: new Address(pk).toScAddress(),
93
- nonce,
94
- signatureExpirationLedger: 0,
95
- // replaced
96
- signature: types.ScVal.scvVec([])
97
- // replaced
98
- })
99
- )
99
+ credentials: authV2 ? types.SorobanCredentials.sorobanCredentialsAddressV2(addressCredentials) : types.SorobanCredentials.sorobanCredentialsAddress(addressCredentials)
100
100
  });
101
101
  return authorizeEntry(entry, signer, validUntilLedgerSeq, networkPassphrase);
102
102
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sources":["../../../src/base/auth.ts"],"sourcesContent":["import xdr from \"./xdr.js\";\n\nimport { Keypair } from \"./keypair.js\";\nimport { StrKey } from \"./strkey.js\";\n\nimport type { Networks } from \"./network.js\";\nimport { hash } from \"./hashing.js\";\n\nimport { Address } from \"./address.js\";\nimport { nativeToScVal } from \"./scval.js\";\n\ntype BufferLike = ArrayBuffer | Buffer | Uint8Array;\n\nfunction toBuffer(value: BufferLike): Buffer {\n if (value instanceof ArrayBuffer) {\n return Buffer.from(new Uint8Array(value));\n }\n return Buffer.from(value);\n}\n\n/**\n * A callback for signing an XDR structure representing all of the details\n * necessary to authorize an invocation tree.\n *\n * @param preimage - the entire authorization envelope whose hash you should\n * sign, so that you can inspect the entire structure if necessary (rather\n * than blindly signing a hash)\n *\n * @returns the signature of the raw payload (which is the sha256 hash of the\n * preimage bytes, so `hash(preimage.toXDR())`) either naked, implying it is\n * signed by the key corresponding to the public key in the entry you pass to\n * {@link authorizeEntry} (decipherable from its\n * `credentials().address().address()`), or alongside an explicit `publicKey`.\n */\nexport type SigningCallback = (\n preimage: xdr.HashIdPreimage,\n) => Promise<BufferLike | { signature: BufferLike; publicKey: string }>;\n\n/**\n * Actually authorizes an existing authorization entry using the given\n * credentials and expiration details, returning a signed copy.\n *\n * This \"fills out\" the authorization entry with a signature, indicating to the\n * {@link Operation.invokeHostFunction} its attached to that:\n * - a particular identity (i.e. signing {@link Keypair} or other signer)\n * - approving the execution of an invocation tree (i.e. a simulation-acquired\n * {@link xdr.SorobanAuthorizedInvocation} or otherwise built)\n * - on a particular network (uniquely identified by its passphrase, see\n * {@link Networks})\n * - until a particular ledger sequence is reached.\n *\n * This one lets you pass either a {@link Keypair} (or, more accurately,\n * anything with a `sign(Buffer): Buffer` method) or a callback function (see\n * {@link SigningCallback}) to handle signing the envelope hash.\n *\n * @param entry - an unsigned authorization entry\n * @param signer - either a {@link Keypair} instance or a function which takes a\n * {@link xdr.HashIdPreimageSorobanAuthorization} input payload and returns\n * EITHER\n *\n * (a) an object containing a `signature` of the hash of the raw payload\n * bytes as a Buffer-like and a `publicKey` string representing who just\n * created this signature, or\n * (b) just the naked signature of the hash of the raw payload bytes (where\n * the signing key is implied to be the address in the `entry`).\n *\n * The latter option (b) is JUST for backwards compatibility and will be\n * removed in the future.\n * @param validUntilLedgerSeq - the (exclusive) future ledger sequence number\n * until which this authorization entry should be valid (if\n * `currentLedgerSeq==validUntil`, this is expired)\n * @param networkPassphrase - the network passphrase is incorporated into the\n * signature (see {@link Networks} for options)\n *\n * If using the `SigningCallback` variation, the signer is assumed to be\n * the entry's credential address unless you use the variant that returns\n * the object.\n *\n * @param forAddress - which credential node the signature should be written\n * to. Only relevant for `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES`, where\n * a single entry can be signed by the top-level account and/or any of its\n * (possibly nested) delegates. Per CAP-71-01 every one of these signers\n * signs the *same* payload (bound to the top-level address), so the\n * signature produced here is written to whichever node(s) carry\n * `forAddress`. When omitted, the signature is written to the top-level\n * credentials, which preserves the behavior for `SOROBAN_CREDENTIALS_ADDRESS`\n * / `SOROBAN_CREDENTIALS_ADDRESS_V2` and for accounts whose signing key\n * differs from the credential address (e.g. multisig).\n *\n * @see authorizeInvocation\n * @example\n * ```ts\n * import {\n * SorobanRpc,\n * Transaction,\n * Networks,\n * authorizeEntry\n * } from '@stellar/stellar-sdk';\n *\n * // Assume signPayloadCallback is a well-formed signing callback.\n * //\n * // It might, for example, pop up a modal from a browser extension, send the\n * // transaction to a third-party service for signing, or just do simple\n * // signing via Keypair like it does here:\n * function signPayloadCallback(payload) {\n * return signer.sign(hash(payload.toXDR()));\n * }\n *\n * function multiPartyAuth(\n * server: SorobanRpc.Server,\n * // assume this involves multi-party auth\n * tx: Transaction,\n * ) {\n * return server\n * .simulateTransaction(tx)\n * .then((simResult) => {\n * tx.operations[0].auth.map(entry =>\n * authorizeEntry(\n * entry,\n * signPayloadCallback,\n * currentLedger + 1000,\n * Networks.TESTNET)\n * );\n *\n * return server.prepareTransaction(tx, simResult);\n * })\n * .then((preppedTx) => {\n * preppedTx.sign(source);\n * return server.sendTransaction(preppedTx);\n * });\n * }\n * ```\n */\nexport async function authorizeEntry(\n entry: xdr.SorobanAuthorizationEntry,\n signer: Keypair | SigningCallback,\n validUntilLedgerSeq: number,\n networkPassphrase: string,\n forAddress?: string,\n): Promise<xdr.SorobanAuthorizationEntry> {\n // no-op if it's source account auth\n if (\n entry.credentials().switch().value ===\n xdr.SorobanCredentialsType.sorobanCredentialsSourceAccount().value\n ) {\n return entry;\n }\n\n const clone = xdr.SorobanAuthorizationEntry.fromXDR(entry.toXDR());\n const credentials = clone.credentials();\n const addrAuth = getAddressCredentials(credentials);\n if (addrAuth === null) {\n // We should have already returned if the credentials were source account credentials,\n // so if we can't get address credentials out of this, it's an unsupported credential type.\n throw new Error(`unsupported credential type ${credentials.switch().name}`);\n }\n\n // Set the expiration before building the preimage, so the hash that gets\n // signed commits to the same expiration ledger stored in the credentials.\n // Otherwise the network reconstructs the preimage from the (updated)\n // credentials and the signature no longer matches.\n addrAuth.signatureExpirationLedger(validUntilLedgerSeq);\n\n const preimage = buildAuthorizationEntryPreimage(\n clone,\n validUntilLedgerSeq,\n networkPassphrase,\n );\n\n const payload = hash(preimage.toXDR());\n\n let signature: Buffer;\n let publicKey: string;\n if (typeof signer === \"function\") {\n const sigResult = await signer(preimage);\n if (\n sigResult !== null &&\n typeof sigResult === \"object\" &&\n \"signature\" in sigResult\n ) {\n signature = toBuffer(sigResult.signature);\n publicKey = sigResult.publicKey;\n } else {\n // if using the deprecated form, assume it's for the entry\n signature = toBuffer(sigResult);\n publicKey = Address.fromScAddress(addrAuth.address()).toString();\n }\n } else {\n signature = toBuffer(signer.sign(payload));\n publicKey = signer.publicKey();\n }\n\n if (!Keypair.fromPublicKey(publicKey).verify(payload, signature)) {\n throw new Error(`signature doesn't match payload`);\n }\n\n // This structure is defined here:\n // https://soroban.stellar.org/docs/fundamentals-and-concepts/invoking-contracts-with-transactions#stellar-account-signatures\n //\n // Encoding a contract structure as an ScVal means the map keys are supposed\n // to be symbols, hence the forced typing here.\n const sigScVal = nativeToScVal(\n {\n public_key: StrKey.decodeEd25519PublicKey(publicKey),\n signature,\n },\n {\n type: {\n public_key: [\"symbol\", null],\n signature: [\"symbol\", null],\n },\n },\n );\n\n const signatureScVal = xdr.ScVal.scvVec([sigScVal]);\n\n // CAP-71-01: the signature payload is shared across the top-level address\n // and every (possibly nested) delegate, so this signer's signature is\n // written to whichever credential node(s) carry `forAddress`. When no\n // `forAddress` is given we fall back to the top-level credentials, which\n // preserves the behavior for ADDRESS / ADDRESS_V2 and for accounts whose\n // signing key differs from the credential address (e.g. multisig).\n const targets: SignableCredential[] =\n forAddress === undefined\n ? [addrAuth]\n : collectSignatureNodes(credentials).filter(\n (node) =>\n Address.fromScAddress(node.address()).toString() === forAddress,\n );\n\n if (targets.length === 0) {\n throw new Error(\n `the authorization entry has no credential node for address ${forAddress}`,\n );\n }\n\n targets.forEach((node) => node.signature(signatureScVal));\n return clone;\n}\n\n/**\n * This builds an entry from scratch, allowing you to express authorization as a\n * function of:\n * - a particular identity (i.e. signing {@link Keypair} or other signer)\n * - approving the execution of an invocation tree (i.e. a simulation-acquired\n * {@link xdr.SorobanAuthorizedInvocation} or otherwise built)\n * - on a particular network (uniquely identified by its passphrase, see\n * {@link Networks})\n * - until a particular ledger sequence is reached.\n *\n * This is in contrast to {@link authorizeEntry}, which signs an existing entry.\n *\n * @param params - the parameters for building and signing the authorization\n * - `signer`: either a {@link Keypair} instance (or anything with a\n * `.sign(buf): Buffer-like` method) or a function which takes a payload (a\n * {@link xdr.HashIdPreimageSorobanAuthorization} instance) input and returns\n * the signature of the hash of the raw payload bytes (where the signing key\n * should correspond to the address in the `entry`)\n * - `validUntilLedgerSeq`: the (exclusive) future ledger sequence\n * number until which this authorization entry should be valid (if\n * `currentLedgerSeq==validUntilLedgerSeq`, this is expired)\n * - `invocation`: the invocation tree that we're authorizing\n * (likely, this comes from transaction simulation)\n * - `networkPassphrase`: the network passphrase is incorporated into\n * the signature (see {@link Networks} for options)\n * - `publicKey`: the public identity of the signer (when providing a\n * {@link Keypair} to `signer`, this can be omitted, as it just uses\n * {@link Keypair.publicKey})\n *\n * @see authorizeEntry\n */\nexport interface AuthorizeInvocationParams {\n signer: Keypair | SigningCallback;\n validUntilLedgerSeq: number;\n invocation: xdr.SorobanAuthorizedInvocation;\n networkPassphrase: string;\n publicKey?: string;\n}\n\nexport function authorizeInvocation(\n params: AuthorizeInvocationParams,\n): Promise<xdr.SorobanAuthorizationEntry> {\n const {\n signer,\n validUntilLedgerSeq,\n invocation,\n networkPassphrase,\n publicKey = \"\",\n } = params;\n // We use keypairs as a source of randomness for the nonce to avoid mucking\n // with any crypto dependencies. Note that this just has to be random and\n // unique, not cryptographically secure, so it's fine.\n const kp = Keypair.random().rawPublicKey();\n const nonce = new xdr.Int64(bytesToInt64(kp));\n\n const pk =\n publicKey || (signer instanceof Keypair ? signer.publicKey() : null);\n if (!pk) {\n throw new Error(`authorizeInvocation requires publicKey parameter`);\n }\n\n const entry = new xdr.SorobanAuthorizationEntry({\n rootInvocation: invocation,\n credentials: xdr.SorobanCredentials.sorobanCredentialsAddressV2(\n new xdr.SorobanAddressCredentials({\n address: new Address(pk).toScAddress(),\n nonce,\n signatureExpirationLedger: 0, // replaced\n signature: xdr.ScVal.scvVec([]), // replaced\n }),\n ),\n });\n\n return authorizeEntry(entry, signer, validUntilLedgerSeq, networkPassphrase);\n}\n\n/**\n * Builds the {@link xdr.HashIdPreimage} whose hash a signer must sign to\n * authorize `entry`. This is the low-level signature payload used by\n * {@link authorizeEntry}, exposed for callers that drive signing themselves —\n * most notably for `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES`, where the\n * client (not simulation) decides which delegates sign and how.\n *\n * For `SOROBAN_CREDENTIALS_ADDRESS` this is the legacy, non-address-bound\n * `ENVELOPE_TYPE_SOROBAN_AUTHORIZATION` preimage. For `SOROBAN_CREDENTIALS_ADDRESS_V2`\n * and `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES` it is the address-bound\n * `ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESS` preimage (CAP-71). For the\n * delegates variant this single payload — bound to the *top-level* address — is\n * what the top-level account and every (nested) delegate each sign.\n *\n * To get the raw bytes to sign, hash the XDR: `hash(preimage.toXDR())`.\n *\n * @param entry - the authorization entry to build the payload for\n * @param validUntilLedgerSeq - the expiration ledger committed into the payload\n * (must match the `signatureExpirationLedger` on the credentials you submit)\n * @param networkPassphrase - the network passphrase mixed into the payload\n * @throws `Error` if `entry` carries source-account or otherwise non-address\n * credentials\n */\nexport function buildAuthorizationEntryPreimage(\n entry: xdr.SorobanAuthorizationEntry,\n validUntilLedgerSeq: number,\n networkPassphrase: string,\n): xdr.HashIdPreimage {\n const credentials = entry.credentials();\n const addrAuth = getAddressCredentials(credentials);\n if (addrAuth === null) {\n throw new Error(\n `cannot build a signature payload for credential type ${credentials.switch().name}`,\n );\n }\n\n const networkId = hash(Buffer.from(networkPassphrase));\n\n switch (credentials.switch().value) {\n // legacy address credentials are not address-bound\n case xdr.SorobanCredentialsType.sorobanCredentialsAddress().value:\n return xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(\n new xdr.HashIdPreimageSorobanAuthorization({\n networkId,\n nonce: addrAuth.nonce(),\n invocation: entry.rootInvocation(),\n signatureExpirationLedger: validUntilLedgerSeq,\n }),\n );\n\n // ADDRESS_V2 and ADDRESS_WITH_DELEGATES bind the address into the signed\n // payload via the WithAddress preimage (CAP-71)\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressV2().value:\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressWithDelegates()\n .value:\n return xdr.HashIdPreimage.envelopeTypeSorobanAuthorizationWithAddress(\n new xdr.HashIdPreimageSorobanAuthorizationWithAddress({\n networkId,\n nonce: addrAuth.nonce(),\n invocation: entry.rootInvocation(),\n address: addrAuth.address(),\n signatureExpirationLedger: validUntilLedgerSeq,\n }),\n );\n\n default:\n throw new Error(\n `unsupported credential type ${credentials.switch().name}`,\n );\n }\n}\n\n/**\n * A delegate signer to attach to a\n * `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES` entry via\n * {@link buildWithDelegatesEntry}.\n */\nexport interface DelegateSignature {\n /** the delegate's address (`G…` account or `C…` contract). */\n address: string;\n /**\n * the delegate's signature value. Defaults to a `scvVoid` placeholder, which\n * you can fill afterwards with {@link authorizeEntry} (passing this address\n * as `forAddress`) or by editing the entry directly.\n */\n signature?: xdr.ScVal;\n /** signers this delegate in turn delegates to (recursive). */\n nestedDelegates?: DelegateSignature[];\n}\n\n/** Parameters for {@link buildWithDelegatesEntry}. */\nexport interface BuildWithDelegatesParams {\n /**\n * an existing `SOROBAN_CREDENTIALS_ADDRESS` or\n * `SOROBAN_CREDENTIALS_ADDRESS_V2` entry — typically one returned by\n * simulation — whose address credentials should be wrapped.\n */\n entry: xdr.SorobanAuthorizationEntry;\n /** the expiration ledger sequence stored on the top-level credentials. */\n validUntilLedgerSeq: number;\n /** the delegate signers to attach. */\n delegates: DelegateSignature[];\n /**\n * the top-level account's signature. Defaults to `scvVoid`, which is valid\n * for accounts that authorize purely via delegated signers (CAP-71-01).\n */\n signature?: xdr.ScVal;\n}\n\n/**\n * Builds a `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES` authorization entry by\n * wrapping the address credentials of an existing `ADDRESS`/`ADDRESS_V2` entry\n * (e.g. one returned by simulation) together with a caller-provided set of\n * delegate signers.\n *\n * Simulation never emits the delegates variant on its own — which accounts use\n * delegated authentication is account-specific policy known only to the client\n * (much like a multisig policy). This helper just assembles the wrapper XDR;\n * you supply the delegate tree (addresses and, optionally, signatures). To\n * produce the signatures, build the shared payload with\n * {@link buildAuthorizationEntryPreimage} on the returned entry and sign it,\n * or fill each node afterwards with {@link authorizeEntry} (passing the\n * signer's address as `forAddress`).\n *\n * Each delegates array (the top-level set and every `nestedDelegates`) is\n * sorted by address in ascending order, and duplicate addresses within an array\n * are rejected, as the protocol requires (CAP-71-01) — otherwise the host\n * rejects the entry.\n *\n * @param params - see {@link BuildWithDelegatesParams}\n * @throws `Error` if `entry` is not an `ADDRESS`/`ADDRESS_V2` entry, or if any\n * delegates array contains a duplicate address.\n */\nexport function buildWithDelegatesEntry(\n params: BuildWithDelegatesParams,\n): xdr.SorobanAuthorizationEntry {\n const { entry, validUntilLedgerSeq, delegates, signature } = params;\n const credentials = entry.credentials();\n const addrAuth = getAddressCredentials(credentials);\n if (\n addrAuth === null ||\n credentials.switch().value ===\n xdr.SorobanCredentialsType.sorobanCredentialsAddressWithDelegates().value\n ) {\n throw new Error(\n `buildWithDelegatesEntry expects ADDRESS or ADDRESS_V2 credentials, got ${\n credentials.switch().name\n }`,\n );\n }\n\n return new xdr.SorobanAuthorizationEntry({\n rootInvocation: entry.rootInvocation(),\n credentials: xdr.SorobanCredentials.sorobanCredentialsAddressWithDelegates(\n new xdr.SorobanAddressCredentialsWithDelegates({\n addressCredentials: new xdr.SorobanAddressCredentials({\n address: addrAuth.address(),\n nonce: addrAuth.nonce(),\n signatureExpirationLedger: validUntilLedgerSeq,\n signature: signature ?? xdr.ScVal.scvVoid(),\n }),\n delegates: buildDelegateNodes(delegates),\n }),\n ),\n });\n}\n\n/**\n * Recursively converts {@link DelegateSignature} descriptors into\n * {@link xdr.SorobanDelegateSignature} nodes, sorting each level by address and\n * rejecting duplicates (CAP-71-01).\n */\nfunction buildDelegateNodes(\n delegates: DelegateSignature[],\n): xdr.SorobanDelegateSignature[] {\n const nodes = delegates.map(\n (delegate) =>\n new xdr.SorobanDelegateSignature({\n address: new Address(delegate.address).toScAddress(),\n signature: delegate.signature ?? xdr.ScVal.scvVoid(),\n nestedDelegates: buildDelegateNodes(delegate.nestedDelegates ?? []),\n }),\n );\n\n nodes.sort((a, b) =>\n Buffer.compare(a.address().toXDR(), b.address().toXDR()),\n );\n\n for (let i = 1; i < nodes.length; i++) {\n if (\n Buffer.compare(\n nodes[i - 1].address().toXDR(),\n nodes[i].address().toXDR(),\n ) === 0\n ) {\n throw new Error(\n `duplicate delegate address ${Address.fromScAddress(\n nodes[i].address(),\n ).toString()}`,\n );\n }\n }\n\n return nodes;\n}\n\n/**\n * Internal helper — intentionally NOT re-exported from `base/index.js`, so it\n * is not part of the public SDK API. Shared with the contract package, which\n * imports it directly from this module. If a public need arises, add it to the\n * explicit auth re-exports in `base/index.ts`.\n *\n * Extracts the {@link xdr.SorobanAddressCredentials} from any address-based\n * Soroban credential, regardless of which credential type variant is used.\n *\n * This unifies access across `SOROBAN_CREDENTIALS_ADDRESS`,\n * `SOROBAN_CREDENTIALS_ADDRESS_V2` (which carries identical fields but binds\n * the address into the signature payload), and\n * `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES` (which wraps the same address\n * credentials alongside a set of delegate signatures).\n *\n * @param credentials - the credentials to inspect\n * @returns the inner address credentials, or `null` for source-account\n * credentials (which carry no address payload)\n */\nexport function getAddressCredentials(\n credentials: xdr.SorobanCredentials,\n): xdr.SorobanAddressCredentials | null {\n switch (credentials.switch().value) {\n case xdr.SorobanCredentialsType.sorobanCredentialsAddress().value:\n return credentials.address();\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressV2().value:\n return credentials.addressV2();\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressWithDelegates()\n .value:\n return credentials.addressWithDelegates().addressCredentials();\n default:\n return null;\n }\n}\n\n/**\n * The common shape of every node in an authorization entry that can carry a\n * signature: the top-level {@link xdr.SorobanAddressCredentials} and, for the\n * delegates variant, each {@link xdr.SorobanDelegateSignature}. Both expose an\n * `address()` and a `signature()` accessor.\n */\ninterface SignableCredential {\n address(value?: xdr.ScAddress): xdr.ScAddress;\n signature(value?: xdr.ScVal): xdr.ScVal;\n}\n\n/**\n * Internal helper. Returns every node in an address-based credential that can\n * carry a signature, in a stable order: the top-level address credentials\n * first, then (only for `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES`) the\n * delegates and their nested delegates, depth-first. Returns an empty array\n * for source-account credentials, which carry no signature.\n *\n * Per CAP-71-01 all of these nodes commit to the same payload (the one bound to\n * the top-level address), so the caller can fill any of them with a signature\n * produced from that shared payload.\n */\nfunction collectSignatureNodes(\n credentials: xdr.SorobanCredentials,\n): SignableCredential[] {\n switch (credentials.switch().value) {\n case xdr.SorobanCredentialsType.sorobanCredentialsAddress().value:\n return [credentials.address()];\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressV2().value:\n return [credentials.addressV2()];\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressWithDelegates()\n .value: {\n const withDelegates = credentials.addressWithDelegates();\n const nodes: SignableCredential[] = [withDelegates.addressCredentials()];\n const walk = (delegates: xdr.SorobanDelegateSignature[]) => {\n delegates.forEach((delegate) => {\n nodes.push(delegate);\n walk(delegate.nestedDelegates());\n });\n };\n walk(withDelegates.delegates());\n return nodes;\n }\n default:\n return [];\n }\n}\n\nfunction bytesToInt64(bytes: Uint8Array): bigint {\n const buf = bytes.subarray(0, 8);\n if (buf.length < 8) {\n throw new Error(\n `need at least 8 bytes to convert to Int64, got ${bytes.length}`,\n );\n }\n const view = new DataView(buf.buffer, buf.byteOffset, 8);\n const value = view.getBigInt64(0, false);\n\n return value;\n}\n"],"names":["xdr"],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sources":["../../../src/base/auth.ts"],"sourcesContent":["import xdr from \"./xdr.js\";\n\nimport { Keypair } from \"./keypair.js\";\nimport { StrKey } from \"./strkey.js\";\n\nimport type { Networks } from \"./network.js\";\nimport { hash } from \"./hashing.js\";\n\nimport { Address } from \"./address.js\";\nimport { nativeToScVal } from \"./scval.js\";\n\ntype BufferLike = ArrayBuffer | Buffer | Uint8Array;\n\nfunction toBuffer(value: BufferLike): Buffer {\n if (value instanceof ArrayBuffer) {\n return Buffer.from(new Uint8Array(value));\n }\n return Buffer.from(value);\n}\n\n/**\n * A callback for signing an XDR structure representing all of the details\n * necessary to authorize an invocation tree.\n *\n * @param preimage - the entire authorization envelope whose hash you should\n * sign, so that you can inspect the entire structure if necessary (rather\n * than blindly signing a hash)\n *\n * @returns the signature of the raw payload (which is the sha256 hash of the\n * preimage bytes, so `hash(preimage.toXDR())`) either naked, implying it is\n * signed by the key corresponding to the public key in the entry you pass to\n * {@link authorizeEntry} (decipherable from its\n * `credentials().address().address()`), or alongside an explicit `publicKey`.\n */\nexport type SigningCallback = (\n preimage: xdr.HashIdPreimage,\n) => Promise<BufferLike | { signature: BufferLike; publicKey: string }>;\n\n/**\n * Actually authorizes an existing authorization entry using the given\n * credentials and expiration details, returning a signed copy.\n *\n * This \"fills out\" the authorization entry with a signature, indicating to the\n * {@link Operation.invokeHostFunction} its attached to that:\n * - a particular identity (i.e. signing {@link Keypair} or other signer)\n * - approving the execution of an invocation tree (i.e. a simulation-acquired\n * {@link xdr.SorobanAuthorizedInvocation} or otherwise built)\n * - on a particular network (uniquely identified by its passphrase, see\n * {@link Networks})\n * - until a particular ledger sequence is reached.\n *\n * This one lets you pass either a {@link Keypair} (or, more accurately,\n * anything with a `sign(Buffer): Buffer` method) or a callback function (see\n * {@link SigningCallback}) to handle signing the envelope hash.\n *\n * @param entry - an unsigned authorization entry\n * @param signer - either a {@link Keypair} instance or a function which takes a\n * {@link xdr.HashIdPreimageSorobanAuthorization} input payload and returns\n * EITHER\n *\n * (a) an object containing a `signature` of the hash of the raw payload\n * bytes as a Buffer-like and a `publicKey` string representing who just\n * created this signature, or\n * (b) just the naked signature of the hash of the raw payload bytes (where\n * the signing key is implied to be the address in the `entry`).\n *\n * The latter option (b) is JUST for backwards compatibility and will be\n * removed in the future.\n * @param validUntilLedgerSeq - the (exclusive) future ledger sequence number\n * until which this authorization entry should be valid (if\n * `currentLedgerSeq==validUntil`, this is expired)\n * @param networkPassphrase - the network passphrase is incorporated into the\n * signature (see {@link Networks} for options)\n *\n * If using the `SigningCallback` variation, the signer is assumed to be\n * the entry's credential address unless you use the variant that returns\n * the object.\n *\n * @param forAddress - which credential node the signature should be written\n * to. Only relevant for `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES`, where\n * a single entry can be signed by the top-level account and/or any of its\n * (possibly nested) delegates. Per CAP-71-01 every one of these signers\n * signs the *same* payload (bound to the top-level address), so the\n * signature produced here is written to whichever node(s) carry\n * `forAddress`. When omitted, the signature is written to the top-level\n * credentials, which preserves the behavior for `SOROBAN_CREDENTIALS_ADDRESS`\n * / `SOROBAN_CREDENTIALS_ADDRESS_V2` and for accounts whose signing key\n * differs from the credential address (e.g. multisig).\n *\n * @see authorizeInvocation\n * @example\n * ```ts\n * import {\n * SorobanRpc,\n * Transaction,\n * Networks,\n * authorizeEntry\n * } from '@stellar/stellar-sdk';\n *\n * // Assume signPayloadCallback is a well-formed signing callback.\n * //\n * // It might, for example, pop up a modal from a browser extension, send the\n * // transaction to a third-party service for signing, or just do simple\n * // signing via Keypair like it does here:\n * function signPayloadCallback(payload) {\n * return signer.sign(hash(payload.toXDR()));\n * }\n *\n * function multiPartyAuth(\n * server: SorobanRpc.Server,\n * // assume this involves multi-party auth\n * tx: Transaction,\n * ) {\n * return server\n * .simulateTransaction(tx)\n * .then((simResult) => {\n * tx.operations[0].auth.map(entry =>\n * authorizeEntry(\n * entry,\n * signPayloadCallback,\n * currentLedger + 1000,\n * Networks.TESTNET)\n * );\n *\n * return server.prepareTransaction(tx, simResult);\n * })\n * .then((preppedTx) => {\n * preppedTx.sign(source);\n * return server.sendTransaction(preppedTx);\n * });\n * }\n * ```\n */\nexport async function authorizeEntry(\n entry: xdr.SorobanAuthorizationEntry,\n signer: Keypair | SigningCallback,\n validUntilLedgerSeq: number,\n networkPassphrase: string,\n forAddress?: string,\n): Promise<xdr.SorobanAuthorizationEntry> {\n // no-op if it's source account auth\n if (\n entry.credentials().switch().value ===\n xdr.SorobanCredentialsType.sorobanCredentialsSourceAccount().value\n ) {\n return entry;\n }\n\n const clone = xdr.SorobanAuthorizationEntry.fromXDR(entry.toXDR());\n const credentials = clone.credentials();\n const addrAuth = getAddressCredentials(credentials);\n if (addrAuth === null) {\n // We should have already returned if the credentials were source account credentials,\n // so if we can't get address credentials out of this, it's an unsupported credential type.\n throw new Error(`unsupported credential type ${credentials.switch().name}`);\n }\n\n // Set the expiration before building the preimage, so the hash that gets\n // signed commits to the same expiration ledger stored in the credentials.\n // Otherwise the network reconstructs the preimage from the (updated)\n // credentials and the signature no longer matches.\n addrAuth.signatureExpirationLedger(validUntilLedgerSeq);\n\n const preimage = buildAuthorizationEntryPreimage(\n clone,\n validUntilLedgerSeq,\n networkPassphrase,\n );\n\n const payload = hash(preimage.toXDR());\n\n let signature: Buffer;\n let publicKey: string;\n if (typeof signer === \"function\") {\n const sigResult = await signer(preimage);\n if (\n sigResult !== null &&\n typeof sigResult === \"object\" &&\n \"signature\" in sigResult\n ) {\n signature = toBuffer(sigResult.signature);\n publicKey = sigResult.publicKey;\n } else {\n // if using the deprecated form, assume it's for the entry\n signature = toBuffer(sigResult);\n publicKey = Address.fromScAddress(addrAuth.address()).toString();\n }\n } else {\n signature = toBuffer(signer.sign(payload));\n publicKey = signer.publicKey();\n }\n\n if (!Keypair.fromPublicKey(publicKey).verify(payload, signature)) {\n throw new Error(`signature doesn't match payload`);\n }\n\n // This structure is defined here:\n // https://soroban.stellar.org/docs/fundamentals-and-concepts/invoking-contracts-with-transactions#stellar-account-signatures\n //\n // Encoding a contract structure as an ScVal means the map keys are supposed\n // to be symbols, hence the forced typing here.\n const sigScVal = nativeToScVal(\n {\n public_key: StrKey.decodeEd25519PublicKey(publicKey),\n signature,\n },\n {\n type: {\n public_key: [\"symbol\", null],\n signature: [\"symbol\", null],\n },\n },\n );\n\n const signatureScVal = xdr.ScVal.scvVec([sigScVal]);\n\n // CAP-71-01: the signature payload is shared across the top-level address\n // and every (possibly nested) delegate, so this signer's signature is\n // written to whichever credential node(s) carry `forAddress`. When no\n // `forAddress` is given we fall back to the top-level credentials, which\n // preserves the behavior for ADDRESS / ADDRESS_V2 and for accounts whose\n // signing key differs from the credential address (e.g. multisig).\n const targets: SignableCredential[] =\n forAddress === undefined\n ? [addrAuth]\n : collectSignatureNodes(credentials).filter(\n (node) =>\n Address.fromScAddress(node.address()).toString() === forAddress,\n );\n\n if (targets.length === 0) {\n throw new Error(\n `the authorization entry has no credential node for address ${forAddress}`,\n );\n }\n\n targets.forEach((node) => node.signature(signatureScVal));\n return clone;\n}\n\nexport interface AuthorizeInvocationParams {\n signer: Keypair | SigningCallback;\n validUntilLedgerSeq: number;\n invocation: xdr.SorobanAuthorizedInvocation;\n networkPassphrase: string;\n publicKey?: string;\n /**\n * Build `SOROBAN_CREDENTIALS_ADDRESS_V2` (CAP-71) credentials instead of the\n * legacy `SOROBAN_CREDENTIALS_ADDRESS`. V2 credentials bind the address into\n * the signed payload but are only valid on networks that have activated\n * CAP-71, so leave this off until the activation vote passes for your target\n * network. The default flips to `true` once V2 becomes mandatory.\n * @defaultValue false\n */\n authV2?: boolean;\n}\n/**\n * This builds an entry from scratch, allowing you to express authorization as a\n * function of:\n * - a particular identity (i.e. signing {@link Keypair} or other signer)\n * - approving the execution of an invocation tree (i.e. a simulation-acquired\n * {@link xdr.SorobanAuthorizedInvocation} or otherwise built)\n * - on a particular network (uniquely identified by its passphrase, see\n * {@link Networks})\n * - until a particular ledger sequence is reached.\n *\n * This is in contrast to {@link authorizeEntry}, which signs an existing entry.\n *\n * @param params - the parameters for building and signing the authorization\n * - `signer`: either a {@link Keypair} instance (or anything with a\n * `.sign(buf): Buffer-like` method) or a function which takes a payload (a\n * {@link xdr.HashIdPreimageSorobanAuthorization} instance) input and returns\n * the signature of the hash of the raw payload bytes (where the signing key\n * should correspond to the address in the `entry`)\n * - `validUntilLedgerSeq`: the (exclusive) future ledger sequence\n * number until which this authorization entry should be valid (if\n * `currentLedgerSeq==validUntilLedgerSeq`, this is expired)\n * - `invocation`: the invocation tree that we're authorizing\n * (likely, this comes from transaction simulation)\n * - `networkPassphrase`: the network passphrase is incorporated into\n * the signature (see {@link Networks} for options)\n * - `publicKey`: the public identity of the signer (when providing a\n * {@link Keypair} to `signer`, this can be omitted, as it just uses\n * {@link Keypair.publicKey})\n * - `authV2`: build `SOROBAN_CREDENTIALS_ADDRESS_V2` (CAP-71) credentials\n * rather than the legacy `SOROBAN_CREDENTIALS_ADDRESS`. Defaults to `false`;\n * only enable it for networks that have activated CAP-71.\n *\n * @see authorizeEntry\n */\nexport function authorizeInvocation(\n params: AuthorizeInvocationParams,\n): Promise<xdr.SorobanAuthorizationEntry> {\n const {\n signer,\n validUntilLedgerSeq,\n invocation,\n networkPassphrase,\n publicKey = \"\",\n authV2 = false,\n } = params;\n // We use keypairs as a source of randomness for the nonce to avoid mucking\n // with any crypto dependencies. Note that this just has to be random and\n // unique, not cryptographically secure, so it's fine.\n const kp = Keypair.random().rawPublicKey();\n const nonce = new xdr.Int64(bytesToInt64(kp));\n\n const pk =\n publicKey || (signer instanceof Keypair ? signer.publicKey() : null);\n if (!pk) {\n throw new Error(`authorizeInvocation requires publicKey parameter`);\n }\n\n // V1 and V2 carry the identical SorobanAddressCredentials payload; only the\n // credential union arm differs. authorizeEntry picks the matching signature\n // preimage (legacy vs. address-bound) off whichever arm we build here.\n const addressCredentials = new xdr.SorobanAddressCredentials({\n address: new Address(pk).toScAddress(),\n nonce,\n signatureExpirationLedger: 0, // replaced\n signature: xdr.ScVal.scvVec([]), // replaced\n });\n\n const entry = new xdr.SorobanAuthorizationEntry({\n rootInvocation: invocation,\n credentials: authV2\n ? xdr.SorobanCredentials.sorobanCredentialsAddressV2(addressCredentials)\n : xdr.SorobanCredentials.sorobanCredentialsAddress(addressCredentials),\n });\n\n return authorizeEntry(entry, signer, validUntilLedgerSeq, networkPassphrase);\n}\n\n/**\n * Builds the {@link xdr.HashIdPreimage} whose hash a signer must sign to\n * authorize `entry`. This is the low-level signature payload used by\n * {@link authorizeEntry}, exposed for callers that drive signing themselves —\n * most notably for `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES`, where the\n * client (not simulation) decides which delegates sign and how.\n *\n * For `SOROBAN_CREDENTIALS_ADDRESS` this is the legacy, non-address-bound\n * `ENVELOPE_TYPE_SOROBAN_AUTHORIZATION` preimage. For `SOROBAN_CREDENTIALS_ADDRESS_V2`\n * and `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES` it is the address-bound\n * `ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESS` preimage (CAP-71). For the\n * delegates variant this single payload — bound to the *top-level* address — is\n * what the top-level account and every (nested) delegate each sign.\n *\n * To get the raw bytes to sign, hash the XDR: `hash(preimage.toXDR())`.\n *\n * @param entry - the authorization entry to build the payload for\n * @param validUntilLedgerSeq - the expiration ledger committed into the payload\n * (must match the `signatureExpirationLedger` on the credentials you submit)\n * @param networkPassphrase - the network passphrase mixed into the payload\n * @throws `Error` if `entry` carries source-account or otherwise non-address\n * credentials\n */\nexport function buildAuthorizationEntryPreimage(\n entry: xdr.SorobanAuthorizationEntry,\n validUntilLedgerSeq: number,\n networkPassphrase: string,\n): xdr.HashIdPreimage {\n const credentials = entry.credentials();\n const addrAuth = getAddressCredentials(credentials);\n if (addrAuth === null) {\n throw new Error(\n `cannot build a signature payload for credential type ${credentials.switch().name}`,\n );\n }\n\n const networkId = hash(Buffer.from(networkPassphrase));\n\n switch (credentials.switch().value) {\n // legacy address credentials are not address-bound\n case xdr.SorobanCredentialsType.sorobanCredentialsAddress().value:\n return xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(\n new xdr.HashIdPreimageSorobanAuthorization({\n networkId,\n nonce: addrAuth.nonce(),\n invocation: entry.rootInvocation(),\n signatureExpirationLedger: validUntilLedgerSeq,\n }),\n );\n\n // ADDRESS_V2 and ADDRESS_WITH_DELEGATES bind the address into the signed\n // payload via the WithAddress preimage (CAP-71)\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressV2().value:\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressWithDelegates()\n .value:\n return xdr.HashIdPreimage.envelopeTypeSorobanAuthorizationWithAddress(\n new xdr.HashIdPreimageSorobanAuthorizationWithAddress({\n networkId,\n nonce: addrAuth.nonce(),\n invocation: entry.rootInvocation(),\n address: addrAuth.address(),\n signatureExpirationLedger: validUntilLedgerSeq,\n }),\n );\n\n default:\n throw new Error(\n `unsupported credential type ${credentials.switch().name}`,\n );\n }\n}\n\n/**\n * A delegate signer to attach to a\n * `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES` entry via\n * {@link buildWithDelegatesEntry}.\n */\nexport interface DelegateSignature {\n /** the delegate's address (`G…` account or `C…` contract). */\n address: string;\n /**\n * the delegate's signature value. Defaults to a `scvVoid` placeholder, which\n * you can fill afterwards with {@link authorizeEntry} (passing this address\n * as `forAddress`) or by editing the entry directly.\n */\n signature?: xdr.ScVal;\n /** signers this delegate in turn delegates to (recursive). */\n nestedDelegates?: DelegateSignature[];\n}\n\n/** Parameters for {@link buildWithDelegatesEntry}. */\nexport interface BuildWithDelegatesParams {\n /**\n * an existing `SOROBAN_CREDENTIALS_ADDRESS` or\n * `SOROBAN_CREDENTIALS_ADDRESS_V2` entry — typically one returned by\n * simulation — whose address credentials should be wrapped.\n */\n entry: xdr.SorobanAuthorizationEntry;\n /** the expiration ledger sequence stored on the top-level credentials. */\n validUntilLedgerSeq: number;\n /** the delegate signers to attach. */\n delegates: DelegateSignature[];\n /**\n * the top-level account's signature. Defaults to `scvVoid`, which is valid\n * for accounts that authorize purely via delegated signers (CAP-71-01).\n */\n signature?: xdr.ScVal;\n}\n\n/**\n * Builds a `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES` authorization entry by\n * wrapping the address credentials of an existing `ADDRESS`/`ADDRESS_V2` entry\n * (e.g. one returned by simulation) together with a caller-provided set of\n * delegate signers.\n *\n * Simulation never emits the delegates variant on its own — which accounts use\n * delegated authentication is account-specific policy known only to the client\n * (much like a multisig policy). This helper just assembles the wrapper XDR;\n * you supply the delegate tree (addresses and, optionally, signatures). To\n * produce the signatures, build the shared payload with\n * {@link buildAuthorizationEntryPreimage} on the returned entry and sign it,\n * or fill each node afterwards with {@link authorizeEntry} (passing the\n * signer's address as `forAddress`).\n *\n * Each delegates array (the top-level set and every `nestedDelegates`) is\n * sorted by address in ascending order, and duplicate addresses within an array\n * are rejected, as the protocol requires (CAP-71-01) — otherwise the host\n * rejects the entry.\n *\n * @param params - see {@link BuildWithDelegatesParams}\n * @throws `Error` if `entry` is not an `ADDRESS`/`ADDRESS_V2` entry, or if any\n * delegates array contains a duplicate address.\n */\nexport function buildWithDelegatesEntry(\n params: BuildWithDelegatesParams,\n): xdr.SorobanAuthorizationEntry {\n const { entry, validUntilLedgerSeq, delegates, signature } = params;\n const credentials = entry.credentials();\n const addrAuth = getAddressCredentials(credentials);\n if (\n addrAuth === null ||\n credentials.switch().value ===\n xdr.SorobanCredentialsType.sorobanCredentialsAddressWithDelegates().value\n ) {\n throw new Error(\n `buildWithDelegatesEntry expects ADDRESS or ADDRESS_V2 credentials, got ${\n credentials.switch().name\n }`,\n );\n }\n\n return new xdr.SorobanAuthorizationEntry({\n rootInvocation: entry.rootInvocation(),\n credentials: xdr.SorobanCredentials.sorobanCredentialsAddressWithDelegates(\n new xdr.SorobanAddressCredentialsWithDelegates({\n addressCredentials: new xdr.SorobanAddressCredentials({\n address: addrAuth.address(),\n nonce: addrAuth.nonce(),\n signatureExpirationLedger: validUntilLedgerSeq,\n signature: signature ?? xdr.ScVal.scvVoid(),\n }),\n delegates: buildDelegateNodes(delegates),\n }),\n ),\n });\n}\n\n/**\n * Recursively converts {@link DelegateSignature} descriptors into\n * {@link xdr.SorobanDelegateSignature} nodes, sorting each level by address and\n * rejecting duplicates (CAP-71-01).\n */\nfunction buildDelegateNodes(\n delegates: DelegateSignature[],\n): xdr.SorobanDelegateSignature[] {\n const nodes = delegates.map(\n (delegate) =>\n new xdr.SorobanDelegateSignature({\n address: new Address(delegate.address).toScAddress(),\n signature: delegate.signature ?? xdr.ScVal.scvVoid(),\n nestedDelegates: buildDelegateNodes(delegate.nestedDelegates ?? []),\n }),\n );\n\n nodes.sort((a, b) =>\n Buffer.compare(a.address().toXDR(), b.address().toXDR()),\n );\n\n for (let i = 1; i < nodes.length; i++) {\n if (\n Buffer.compare(\n nodes[i - 1].address().toXDR(),\n nodes[i].address().toXDR(),\n ) === 0\n ) {\n throw new Error(\n `duplicate delegate address ${Address.fromScAddress(\n nodes[i].address(),\n ).toString()}`,\n );\n }\n }\n\n return nodes;\n}\n\n/**\n * Internal helper — intentionally NOT re-exported from `base/index.js`, so it\n * is not part of the public SDK API. Shared with the contract package, which\n * imports it directly from this module. If a public need arises, add it to the\n * explicit auth re-exports in `base/index.ts`.\n *\n * Extracts the {@link xdr.SorobanAddressCredentials} from any address-based\n * Soroban credential, regardless of which credential type variant is used.\n *\n * This unifies access across `SOROBAN_CREDENTIALS_ADDRESS`,\n * `SOROBAN_CREDENTIALS_ADDRESS_V2` (which carries identical fields but binds\n * the address into the signature payload), and\n * `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES` (which wraps the same address\n * credentials alongside a set of delegate signatures).\n *\n * @param credentials - the credentials to inspect\n * @returns the inner address credentials, or `null` for source-account\n * credentials (which carry no address payload)\n */\nexport function getAddressCredentials(\n credentials: xdr.SorobanCredentials,\n): xdr.SorobanAddressCredentials | null {\n switch (credentials.switch().value) {\n case xdr.SorobanCredentialsType.sorobanCredentialsAddress().value:\n return credentials.address();\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressV2().value:\n return credentials.addressV2();\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressWithDelegates()\n .value:\n return credentials.addressWithDelegates().addressCredentials();\n default:\n return null;\n }\n}\n\n/**\n * The common shape of every node in an authorization entry that can carry a\n * signature: the top-level {@link xdr.SorobanAddressCredentials} and, for the\n * delegates variant, each {@link xdr.SorobanDelegateSignature}. Both expose an\n * `address()` and a `signature()` accessor.\n */\ninterface SignableCredential {\n address(value?: xdr.ScAddress): xdr.ScAddress;\n signature(value?: xdr.ScVal): xdr.ScVal;\n}\n\n/**\n * Internal helper. Returns every node in an address-based credential that can\n * carry a signature, in a stable order: the top-level address credentials\n * first, then (only for `SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES`) the\n * delegates and their nested delegates, depth-first. Returns an empty array\n * for source-account credentials, which carry no signature.\n *\n * Per CAP-71-01 all of these nodes commit to the same payload (the one bound to\n * the top-level address), so the caller can fill any of them with a signature\n * produced from that shared payload.\n */\nfunction collectSignatureNodes(\n credentials: xdr.SorobanCredentials,\n): SignableCredential[] {\n switch (credentials.switch().value) {\n case xdr.SorobanCredentialsType.sorobanCredentialsAddress().value:\n return [credentials.address()];\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressV2().value:\n return [credentials.addressV2()];\n case xdr.SorobanCredentialsType.sorobanCredentialsAddressWithDelegates()\n .value: {\n const withDelegates = credentials.addressWithDelegates();\n const nodes: SignableCredential[] = [withDelegates.addressCredentials()];\n const walk = (delegates: xdr.SorobanDelegateSignature[]) => {\n delegates.forEach((delegate) => {\n nodes.push(delegate);\n walk(delegate.nestedDelegates());\n });\n };\n walk(withDelegates.delegates());\n return nodes;\n }\n default:\n return [];\n }\n}\n\nfunction bytesToInt64(bytes: Uint8Array): bigint {\n const buf = bytes.subarray(0, 8);\n if (buf.length < 8) {\n throw new Error(\n `need at least 8 bytes to convert to Int64, got ${bytes.length}`,\n );\n }\n const view = new DataView(buf.buffer, buf.byteOffset, 8);\n const value = view.getBigInt64(0, false);\n\n return value;\n}\n"],"names":["xdr"],"mappings":"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"}
@@ -89,7 +89,7 @@ class Keypair {
89
89
  * Create a random `Keypair` object.
90
90
  */
91
91
  static random() {
92
- const { secretKey } = ed.keygen();
92
+ const secretKey = ed.utils.randomSecretKey();
93
93
  return this.fromRawEd25519Seed(Buffer.from(secretKey));
94
94
  }
95
95
  /** Returns this public key as an xdr.AccountId. */
@@ -1 +1 @@
1
- {"version":3,"file":"keypair.js","sources":["../../../src/base/keypair.ts"],"sourcesContent":["import * as ed from \"@noble/ed25519\";\nimport { sha512 } from \"@noble/hashes/sha2.js\";\nimport { sign, verify, generate } from \"./signing.js\";\nimport { StrKey } from \"./strkey.js\";\nimport { hash } from \"./hashing.js\";\n\nimport xdr from \"./xdr.js\";\n\ned.hashes.sha512 = sha512;\n/**\n * `Keypair` represents public (and secret) keys of the account.\n *\n * Currently `Keypair` only supports ed25519 but in a future this class can be abstraction layer for other\n * public-key signature systems.\n *\n * Use more convenient methods to create `Keypair` object:\n * * `{@link Keypair.fromPublicKey}`\n * * `{@link Keypair.fromSecret}`\n * * `{@link Keypair.random}`\n */\nexport class Keypair {\n readonly type: \"ed25519\";\n private _publicKey: Buffer;\n private _secretSeed?: Buffer;\n private _secretKey?: Buffer;\n\n /**\n * @param keys - at least one of keys must be provided.\n * - `type`: public-key signature system name (currently only `ed25519` keys are supported)\n * - `publicKey`: raw public key\n * - `secretKey`: raw secret key (32-byte secret seed in ed25519)\n */\n constructor(\n keys:\n | {\n type: \"ed25519\";\n secretKey: Buffer | string;\n publicKey?: Buffer | string;\n }\n | { type: \"ed25519\"; publicKey: Buffer | string },\n ) {\n if (keys.type !== \"ed25519\") {\n throw new Error(\"Invalid keys type\");\n }\n\n this.type = keys.type;\n\n if (\"secretKey\" in keys) {\n keys.secretKey = Buffer.from(keys.secretKey);\n\n if (keys.secretKey.length !== 32) {\n throw new Error(\"secretKey length is invalid\");\n }\n\n this._secretSeed = keys.secretKey;\n this._publicKey = generate(keys.secretKey);\n this._secretKey = keys.secretKey;\n\n if (\n keys.publicKey &&\n !this._publicKey.equals(Buffer.from(keys.publicKey))\n ) {\n throw new Error(\"secretKey does not match publicKey\");\n }\n } else if (\"publicKey\" in keys) {\n this._publicKey = Buffer.from(keys.publicKey);\n\n if (this._publicKey.length !== 32) {\n throw new Error(\"publicKey length is invalid\");\n }\n } else {\n throw new Error(\n \"At least one of publicKey or secretKey must be provided\",\n );\n }\n }\n\n /**\n * Creates a new `Keypair` instance from secret. This can either be secret key or secret seed depending\n * on underlying public-key signature system. Currently `Keypair` only supports ed25519.\n * @param secret - secret key (ex. `SDAK....`)\n */\n static fromSecret(secret: string): Keypair {\n const rawSecret = StrKey.decodeEd25519SecretSeed(secret);\n return this.fromRawEd25519Seed(rawSecret);\n }\n\n /**\n * Creates a new `Keypair` object from ed25519 secret key seed raw bytes.\n *\n * @param rawSeed - raw 32-byte ed25519 secret key seed\n */\n static fromRawEd25519Seed(rawSeed: Buffer): Keypair {\n return new this({ type: \"ed25519\", secretKey: rawSeed });\n }\n\n /**\n * Returns `Keypair` object representing network master key.\n * @param networkPassphrase - passphrase of the target stellar network (e.g. \"Public Global Stellar Network ; September 2015\")\n */\n static master(networkPassphrase: string): Keypair {\n if (!networkPassphrase) {\n throw new Error(\n \"No network selected. Please pass a network argument, e.g. `Keypair.master(Networks.PUBLIC)`.\",\n );\n }\n\n return this.fromRawEd25519Seed(hash(networkPassphrase));\n }\n\n /**\n * Creates a new `Keypair` object from public key.\n * @param publicKey - public key (ex. `GB3KJPLFUYN5VL6R3GU3EGCGVCKFDSD7BEDX42HWG5BWFKB3KQGJJRMA`)\n */\n static fromPublicKey(publicKey: string): Keypair {\n const publicKeyBuffer = StrKey.decodeEd25519PublicKey(publicKey);\n if (publicKeyBuffer.length !== 32) {\n throw new Error(\"Invalid Stellar public key\");\n }\n\n return new this({ type: \"ed25519\", publicKey: publicKeyBuffer });\n }\n\n /**\n * Create a random `Keypair` object.\n */\n static random(): Keypair {\n const { secretKey } = ed.keygen();\n return this.fromRawEd25519Seed(Buffer.from(secretKey));\n }\n\n /** Returns this public key as an xdr.AccountId. */\n xdrAccountId(): xdr.AccountId {\n return xdr.PublicKey.publicKeyTypeEd25519(this._publicKey);\n }\n\n /** Returns this public key as an xdr.PublicKey. */\n xdrPublicKey(): xdr.PublicKey {\n return xdr.PublicKey.publicKeyTypeEd25519(this._publicKey);\n }\n\n /**\n * Creates a {@link xdr.MuxedAccount} object from the public key.\n *\n * You will get a different type of muxed account depending on whether or not\n * you pass an ID.\n *\n * @param id - (optional) stringified integer indicating the underlying muxed\n * ID of the new account object\n */\n xdrMuxedAccount(id?: string): xdr.MuxedAccount {\n if (typeof id !== \"undefined\") {\n if (typeof id !== \"string\") {\n throw new TypeError(`expected string for ID, got ${typeof id}`);\n }\n\n return xdr.MuxedAccount.keyTypeMuxedEd25519(\n new xdr.MuxedAccountMed25519({\n id: xdr.Uint64.fromString(id),\n ed25519: this._publicKey,\n }),\n );\n }\n\n return xdr.MuxedAccount.keyTypeEd25519(this._publicKey);\n }\n\n /**\n * Returns raw public key bytes\n */\n rawPublicKey(): Buffer {\n return this._publicKey;\n }\n\n /**\n * Returns the signature hint for this keypair.\n * The hint is the last 4 bytes of the account ID XDR representation.\n */\n signatureHint(): Buffer {\n const a = this.xdrAccountId().toXDR();\n\n return a.subarray(a.length - 4);\n }\n\n /**\n * Returns public key associated with this `Keypair` object.\n */\n publicKey(): string {\n return StrKey.encodeEd25519PublicKey(this._publicKey);\n }\n\n /**\n * Returns secret key associated with this `Keypair` object.\n *\n * The secret key is encoded in Stellar format (e.g., `SDAK....`).\n *\n * @throws if no secret key is available\n */\n secret(): string {\n if (!this._secretSeed) {\n throw new Error(\"no secret key available\");\n }\n\n if (this.type === \"ed25519\") {\n return StrKey.encodeEd25519SecretSeed(this._secretSeed);\n }\n\n throw new Error(\"Invalid Keypair type\");\n }\n\n /**\n * Returns raw secret key bytes.\n *\n * @throws if no secret seed is available\n */\n rawSecretKey(): Buffer {\n if (!this._secretSeed) {\n throw new Error(\"no secret seed available\");\n }\n return this._secretSeed;\n }\n\n /**\n * Returns `true` if this `Keypair` object contains secret key and can sign.\n */\n canSign(): boolean {\n return !!this._secretKey;\n }\n\n /**\n * Signs data.\n *\n * @param data - data to sign\n * @throws if no secret key is available\n */\n sign(data: Buffer): Buffer {\n if (!this._secretKey) {\n throw new Error(\"cannot sign: no secret key available\");\n }\n\n return sign(data, this._secretKey);\n }\n\n /**\n * Verifies if `signature` for `data` is valid.\n *\n * @param data - signed data\n * @param signature - signature to verify\n */\n verify(data: Buffer, signature: Buffer): boolean {\n try {\n return verify(data, signature, this._publicKey);\n } catch {\n return false;\n }\n }\n\n /**\n * Returns the decorated signature (hint+sig) for arbitrary data.\n *\n * The returned structure can be added directly to a transaction envelope.\n *\n * @param data - arbitrary data to sign\n *\n * @see TransactionBase.addDecoratedSignature\n */\n signDecorated(data: Buffer): xdr.DecoratedSignature {\n const signature = this.sign(data);\n const hint = this.signatureHint();\n\n return new xdr.DecoratedSignature({ hint, signature });\n }\n\n /**\n * Returns the raw decorated signature (hint+sig) for a signed payload signer.\n *\n * The hint is defined as the last 4 bytes of the signer key XORed with last\n * 4 bytes of the payload (zero-left-padded if necessary).\n *\n * @param data - data to both sign and treat as the payload\n *\n * @see https://github.com/stellar/stellar-protocol/blob/master/core/cap-0040.md#signature-hint\n * @see TransactionBase.addDecoratedSignature\n */\n signPayloadDecorated(data: Buffer): xdr.DecoratedSignature {\n // Ensure data is a Buffer to support array-like inputs\n const dataBuffer = Buffer.isBuffer(data) ? data : Buffer.from(data);\n\n const signature = this.sign(dataBuffer);\n const keyHint = this.signatureHint();\n\n let hint = Buffer.from(dataBuffer.subarray(-4));\n if (hint.length < 4) {\n // append zeroes as needed\n hint = Buffer.concat([hint, Buffer.alloc(4 - hint.length, 0)]);\n }\n\n // XOR each byte of hint with corresponding byte of keyHint\n for (let i = 0; i < hint.length; i++) {\n hint[i] = (hint[i] as number) ^ (keyHint[i] as number);\n }\n\n return new xdr.DecoratedSignature({\n hint,\n signature,\n });\n }\n}\n"],"names":["xdr"],"mappings":"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"}
1
+ {"version":3,"file":"keypair.js","sources":["../../../src/base/keypair.ts"],"sourcesContent":["import * as ed from \"@noble/ed25519\";\nimport { sha512 } from \"@noble/hashes/sha2.js\";\nimport { sign, verify, generate } from \"./signing.js\";\nimport { StrKey } from \"./strkey.js\";\nimport { hash } from \"./hashing.js\";\n\nimport xdr from \"./xdr.js\";\n\ned.hashes.sha512 = sha512;\n/**\n * `Keypair` represents public (and secret) keys of the account.\n *\n * Currently `Keypair` only supports ed25519 but in a future this class can be abstraction layer for other\n * public-key signature systems.\n *\n * Use more convenient methods to create `Keypair` object:\n * * `{@link Keypair.fromPublicKey}`\n * * `{@link Keypair.fromSecret}`\n * * `{@link Keypair.random}`\n */\nexport class Keypair {\n readonly type: \"ed25519\";\n private _publicKey: Buffer;\n private _secretSeed?: Buffer;\n private _secretKey?: Buffer;\n\n /**\n * @param keys - at least one of keys must be provided.\n * - `type`: public-key signature system name (currently only `ed25519` keys are supported)\n * - `publicKey`: raw public key\n * - `secretKey`: raw secret key (32-byte secret seed in ed25519)\n */\n constructor(\n keys:\n | {\n type: \"ed25519\";\n secretKey: Buffer | string;\n publicKey?: Buffer | string;\n }\n | { type: \"ed25519\"; publicKey: Buffer | string },\n ) {\n if (keys.type !== \"ed25519\") {\n throw new Error(\"Invalid keys type\");\n }\n\n this.type = keys.type;\n\n if (\"secretKey\" in keys) {\n keys.secretKey = Buffer.from(keys.secretKey);\n\n if (keys.secretKey.length !== 32) {\n throw new Error(\"secretKey length is invalid\");\n }\n\n this._secretSeed = keys.secretKey;\n this._publicKey = generate(keys.secretKey);\n this._secretKey = keys.secretKey;\n\n if (\n keys.publicKey &&\n !this._publicKey.equals(Buffer.from(keys.publicKey))\n ) {\n throw new Error(\"secretKey does not match publicKey\");\n }\n } else if (\"publicKey\" in keys) {\n this._publicKey = Buffer.from(keys.publicKey);\n\n if (this._publicKey.length !== 32) {\n throw new Error(\"publicKey length is invalid\");\n }\n } else {\n throw new Error(\n \"At least one of publicKey or secretKey must be provided\",\n );\n }\n }\n\n /**\n * Creates a new `Keypair` instance from secret. This can either be secret key or secret seed depending\n * on underlying public-key signature system. Currently `Keypair` only supports ed25519.\n * @param secret - secret key (ex. `SDAK....`)\n */\n static fromSecret(secret: string): Keypair {\n const rawSecret = StrKey.decodeEd25519SecretSeed(secret);\n return this.fromRawEd25519Seed(rawSecret);\n }\n\n /**\n * Creates a new `Keypair` object from ed25519 secret key seed raw bytes.\n *\n * @param rawSeed - raw 32-byte ed25519 secret key seed\n */\n static fromRawEd25519Seed(rawSeed: Buffer): Keypair {\n return new this({ type: \"ed25519\", secretKey: rawSeed });\n }\n\n /**\n * Returns `Keypair` object representing network master key.\n * @param networkPassphrase - passphrase of the target stellar network (e.g. \"Public Global Stellar Network ; September 2015\")\n */\n static master(networkPassphrase: string): Keypair {\n if (!networkPassphrase) {\n throw new Error(\n \"No network selected. Please pass a network argument, e.g. `Keypair.master(Networks.PUBLIC)`.\",\n );\n }\n\n return this.fromRawEd25519Seed(hash(networkPassphrase));\n }\n\n /**\n * Creates a new `Keypair` object from public key.\n * @param publicKey - public key (ex. `GB3KJPLFUYN5VL6R3GU3EGCGVCKFDSD7BEDX42HWG5BWFKB3KQGJJRMA`)\n */\n static fromPublicKey(publicKey: string): Keypair {\n const publicKeyBuffer = StrKey.decodeEd25519PublicKey(publicKey);\n if (publicKeyBuffer.length !== 32) {\n throw new Error(\"Invalid Stellar public key\");\n }\n\n return new this({ type: \"ed25519\", publicKey: publicKeyBuffer });\n }\n\n /**\n * Create a random `Keypair` object.\n */\n static random(): Keypair {\n const secretKey = ed.utils.randomSecretKey();\n return this.fromRawEd25519Seed(Buffer.from(secretKey));\n }\n\n /** Returns this public key as an xdr.AccountId. */\n xdrAccountId(): xdr.AccountId {\n return xdr.PublicKey.publicKeyTypeEd25519(this._publicKey);\n }\n\n /** Returns this public key as an xdr.PublicKey. */\n xdrPublicKey(): xdr.PublicKey {\n return xdr.PublicKey.publicKeyTypeEd25519(this._publicKey);\n }\n\n /**\n * Creates a {@link xdr.MuxedAccount} object from the public key.\n *\n * You will get a different type of muxed account depending on whether or not\n * you pass an ID.\n *\n * @param id - (optional) stringified integer indicating the underlying muxed\n * ID of the new account object\n */\n xdrMuxedAccount(id?: string): xdr.MuxedAccount {\n if (typeof id !== \"undefined\") {\n if (typeof id !== \"string\") {\n throw new TypeError(`expected string for ID, got ${typeof id}`);\n }\n\n return xdr.MuxedAccount.keyTypeMuxedEd25519(\n new xdr.MuxedAccountMed25519({\n id: xdr.Uint64.fromString(id),\n ed25519: this._publicKey,\n }),\n );\n }\n\n return xdr.MuxedAccount.keyTypeEd25519(this._publicKey);\n }\n\n /**\n * Returns raw public key bytes\n */\n rawPublicKey(): Buffer {\n return this._publicKey;\n }\n\n /**\n * Returns the signature hint for this keypair.\n * The hint is the last 4 bytes of the account ID XDR representation.\n */\n signatureHint(): Buffer {\n const a = this.xdrAccountId().toXDR();\n\n return a.subarray(a.length - 4);\n }\n\n /**\n * Returns public key associated with this `Keypair` object.\n */\n publicKey(): string {\n return StrKey.encodeEd25519PublicKey(this._publicKey);\n }\n\n /**\n * Returns secret key associated with this `Keypair` object.\n *\n * The secret key is encoded in Stellar format (e.g., `SDAK....`).\n *\n * @throws if no secret key is available\n */\n secret(): string {\n if (!this._secretSeed) {\n throw new Error(\"no secret key available\");\n }\n\n if (this.type === \"ed25519\") {\n return StrKey.encodeEd25519SecretSeed(this._secretSeed);\n }\n\n throw new Error(\"Invalid Keypair type\");\n }\n\n /**\n * Returns raw secret key bytes.\n *\n * @throws if no secret seed is available\n */\n rawSecretKey(): Buffer {\n if (!this._secretSeed) {\n throw new Error(\"no secret seed available\");\n }\n return this._secretSeed;\n }\n\n /**\n * Returns `true` if this `Keypair` object contains secret key and can sign.\n */\n canSign(): boolean {\n return !!this._secretKey;\n }\n\n /**\n * Signs data.\n *\n * @param data - data to sign\n * @throws if no secret key is available\n */\n sign(data: Buffer): Buffer {\n if (!this._secretKey) {\n throw new Error(\"cannot sign: no secret key available\");\n }\n\n return sign(data, this._secretKey);\n }\n\n /**\n * Verifies if `signature` for `data` is valid.\n *\n * @param data - signed data\n * @param signature - signature to verify\n */\n verify(data: Buffer, signature: Buffer): boolean {\n try {\n return verify(data, signature, this._publicKey);\n } catch {\n return false;\n }\n }\n\n /**\n * Returns the decorated signature (hint+sig) for arbitrary data.\n *\n * The returned structure can be added directly to a transaction envelope.\n *\n * @param data - arbitrary data to sign\n *\n * @see TransactionBase.addDecoratedSignature\n */\n signDecorated(data: Buffer): xdr.DecoratedSignature {\n const signature = this.sign(data);\n const hint = this.signatureHint();\n\n return new xdr.DecoratedSignature({ hint, signature });\n }\n\n /**\n * Returns the raw decorated signature (hint+sig) for a signed payload signer.\n *\n * The hint is defined as the last 4 bytes of the signer key XORed with last\n * 4 bytes of the payload (zero-left-padded if necessary).\n *\n * @param data - data to both sign and treat as the payload\n *\n * @see https://github.com/stellar/stellar-protocol/blob/master/core/cap-0040.md#signature-hint\n * @see TransactionBase.addDecoratedSignature\n */\n signPayloadDecorated(data: Buffer): xdr.DecoratedSignature {\n // Ensure data is a Buffer to support array-like inputs\n const dataBuffer = Buffer.isBuffer(data) ? data : Buffer.from(data);\n\n const signature = this.sign(dataBuffer);\n const keyHint = this.signatureHint();\n\n let hint = Buffer.from(dataBuffer.subarray(-4));\n if (hint.length < 4) {\n // append zeroes as needed\n hint = Buffer.concat([hint, Buffer.alloc(4 - hint.length, 0)]);\n }\n\n // XOR each byte of hint with corresponding byte of keyHint\n for (let i = 0; i < hint.length; i++) {\n hint[i] = (hint[i] as number) ^ (keyHint[i] as number);\n }\n\n return new xdr.DecoratedSignature({\n hint,\n signature,\n });\n }\n}\n"],"names":["xdr"],"mappings":"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"}
@@ -131,7 +131,19 @@ class TransactionBuilder {
131
131
  "cannot clone a transaction with no operations: per-operation base fee cannot be determined"
132
132
  );
133
133
  }
134
- const unscaledFee = Math.floor(parseInt(tx.fee, 10) / tx.operations.length);
134
+ let sorobanData;
135
+ const envelope = tx.toEnvelope();
136
+ if (envelope.switch() === types.EnvelopeType.envelopeTypeTx()) {
137
+ sorobanData = envelope.v1().tx().ext().value() ?? void 0;
138
+ }
139
+ let totalFee = parseInt(tx.fee, 10);
140
+ if (sorobanData) {
141
+ const resourceFee = Number(sorobanData.resourceFee().toBigInt());
142
+ if (totalFee - resourceFee > 0) {
143
+ totalFee -= resourceFee;
144
+ }
145
+ }
146
+ const unscaledFee = Math.floor(totalFee / tx.operations.length);
135
147
  const builderOpts = {
136
148
  fee: (unscaledFee || BASE_FEE).toString(),
137
149
  memo: tx.memo,