Currently we have the following issue with access key nonce: if someone deletes a key and adds the same key back with nonce 0, then old transactions signed with that key can potentially be submitted and processed again, which may cause trouble for the end users.
There are in general two different categories of solutions, representing different views of the problem.
Address the issue on the tooling level
The reasoning here is that users are not supposed to delete a key and add the same key back. This is a practice that can shoot themselves in the foot and must be avoided. Consequently, to prevent users from falling to this trap, client sdks should take care of the issue so that developers don’t have to worry about it. For example, we could always use
current_block_height * 1e6 as a nonce for newly created access keys, or simply use block timestamp. In the context of near-api-js, this would mean changing the following two functions to take nonce as an argument
- near-api-js/transaction.ts at 5265f065ec6f7148928711e6663e51a4ca51738d · near/near-api-js · GitHub
near-api-js/transaction.ts at 5265f065ec6f7148928711e6663e51a4ca51738d · near/near-api-js · GitHub
Correspondingly, we should add this to our docs on access keys so that developers working on devtools are aware of the consequences.
However, one issue with this approach, besides being less reliable, is that this does not prevent duplicate transactions from being included onchain, which, while on its own is fine, causes trouble for rpc and indexer since transaction hash can no longer uniquely identify a transaction.
Address the issue on the protocol level
There are multiple ways to address this issue completely on the protocol level. One way that seems to work well is to require the access key nonce to be
h * 1e6 where
h is the block in which the add key transaction is included and for every transaction signed with the access key afterwards, they must have a nonce no larger than
h * 1e6, where
h is the block in which the transaction is included.
The disadvantage with this approach, besides needing to modify the protocol, is that we impose a range restriction on the access key nonces and as a result, it is not feasible if someone wants to create a key locally, sign some transactions with the key and then submit the add key transaction together with the transactions signed by the key. Note that we are not aware of anyone (including custody provider) who is doing this currently, so it might not be an actual issue.