Repository navigation
[DISCUSSION] - BRC-100 - createAction clarification #79
Description
Activity
I will answer a few of these now, and I'll also ask my team to provide answers to the ones that I haven't covered.
The method is called "create action." Could you clarify what "action" refers to in this context? Is it effectively creating or submitting a transaction?
An Action is a transaction. See "Action Oriented Programming" from https://projectbabbage.com/docs/babbage-sdk/concepts/actions-aop
Action = Bitcoin transaction.
If the only required parameter is description, what occurs if the user provides only this parameter?
Actions need at least one input OR one output. If there is neither, it is an error.
The documentation does not mention the use of labels. Is it allowed to include labels for customization within the wallet? For example, can labels be used as triggers for other operations when a transaction with a specific label is created?
Labels are for allowing a transaction to later be found using
listActions. They cannot be used as triggers, they are for categorization. One transaction can have many labels.What should happen if both inputBEEF and inputs are provided?
When
inputsis provided,inputBEEFis required as an additional parameter. This provides the context for the input.If I already have a prepared transaction and corresponding BEEF data, can I use this endpoint, or should I use a different one?
This endpoint should be used when your goal is to create a new transaction. If your goal is to let a recipient wallet know about a transaction that you've already created, then you should use
internalizeActioninstead.What is the intended purpose of the inputDescription field within the input array?
To allow the user to know the context around when a previous token is consumed.
Why is the inputDescription field required?
Since this field is part of the input object, would it be simpler to call it description instead of inputDescription?It's required so that there's always an accounting of why a particular token was spent, updated, or consumed, for the purpose of the user's record-keeping. It's named this way primarily for historical purposes.
What happens if basket is not provided? Is there a default categorization?
If no basket is provided, then the wallet will not track the output at all, and it will be an untracked output (the wallet will not store information about it, and it can never appear in
listOutputsresults.What is the difference between a transaction label and an output tag?
A transaction label is transaction-level categorization, used when retrieving or filtering a list of transactions (from
listActions). Conversely, an output tag is an output-level categorization, used when retrieving or filtering a list of outputs (fromlistOutputs).Are tags allowed to influence additional customization features, such as triggering specific operations when a transaction with a given tag is created?
We must strike
transactionand replace it with output in the question, as tags are an output-level construct:Are tags allowed to influence additional customization features, such as triggering specific operations when a
transactionoutput with a given tag is created?Output tags, like transaction labels, are a mechanism of categorization and filtering, not a triggering mechanism. They allow tagged outputs to be later retrieved based on various criterion from the wallet, using the
listOutputsmethod.Are there any structural limitations for tags?
Tags must be strings that comply with the restrictions on byte length. Beyond this, tags may be any valid string.
Options, Response values, error handling
Paging @tonesnotes to provide an answer on these.
However, I will speak to the
signableActionstructure, and the points within 5.4, so that Tone does not have to answer that one:It seems that the signable transaction structure might need to be extensible. For example:
The signable action structure is used when a user wants to redeem custom tokens, not controlled by the wallet.
- In most cases, a transaction will be returned and not a signable action.
- If a signable action is returned, it comprises a BEEF v2 structure with missing unlocking scripts on the inputs that are custom, and in need of signature.
- However, in this case, all the outputs and all other inputs are already selected and provided, so that signatures and unlocking scripts can be computed using any arbitrary third-party application logic.
- The unlocking scripts are then provided, together with the reference number, to the
signActionmethod, which then completes the processing of the transaction. - To indicate which inputs are in need of having custom signatures and unlocking scripts computed, we make use of the
inputsarray. For each input, if itsunlockingScriptis provided directly, we do not need to sign it withsignAction. - However, if instead of providing an unlocking script, we provided
unlockingScriptLengthestimate for that input, then the input must be flagged for later signing usingsignAction— application-level code will then callsignActionand provide the required unlocking script.
Because the
signActionprocess, and the mechanisms of utilizing an unlocking script, are custom and related to the specific inputs being dealt with, which may be arbitrary in nature, the process of evaluating the provided unlocking script is not related to any key derivation process of the wallet itself — instead, it is deferred to the rules of the Bitcoin script language, interpreter, and the policies of transaction processors. The wallet does not utilize any key derivation schemes when dealing with arbitrary and custom unlocking scripts on externally-managed tokens.How can a user indicate that one input requires a key with a certain security level and another requires a different level?
A user doe not indicate this to the wallet. Instead, if an input is externally-managed (an application-managed input), then:
- If the user provides
unlockingScriptdirectly, the unlocking script is applied to the input. - If instead, the user provides an
unlockingScriptLengthestimation, then asignableActionis returned, and thesignActionprocess must later be employed by the user in order to provide the correct unlocking script. - However, the mechanism utilized in order to obtain the valid unlocking script does not concern the wallet. It may or may not involve key derivation, or other wallet-related cryptographic operations or signature computations — it may be fully external, utilize sCrypt, or any other external mechanism.
- Thus, the wallet does not deal with keys of differing security levels here, or any other such constructs. Instead, it merely applies the provided custom unlocking script to the foreign UTXO, and evaluates the spend using the script interpreter to determine its validity.
If a new derivation scheme is introduced, would this API need updating, and how would that affect backward compatibility?
A new key derivation scheme will not be required, and the API for transaction creation does not closely relate to key derivation. Beyond the requirement for
internalizeActionto accept payment remittances through a derivation prefix and derivation suffix as described in BRC-29, the underlying mechanism of wallet operations within thecreateAction/signActionscheme is not related to which key derivation scheme the wallet uses.The only methods that are related are related to cryptographic operations, digital signatures, and identity management. For these components, the BKDS (BSV Key Derivation Scheme) is used, and it's a dependency of this specification. There is no backwards-compatibility, and no changes to the scheme are ever permitted by the specification. The key derivation scheme is foundational, and required to be fixed. Any change would break all implementations.
If a wallet still uses an older derivation scheme (like BIP32), how can this API accommodate it so that more wallets can conform without enforcing a full migration to a new scheme?
This specification forces compatibility with a new scheme, and forces a full migration to the new system. BIP32 is fundamentally incompatible with the primitives used for all foundational operations, including identity management and digital certificates. Use of this older scheme would open many attack vectors and privacy issues. To achieve compliance, wallets must upgrade to BKDS.
Reacted by deggenOptions
What occurs if signAndProcess is not provided?
Many options are opitonal boolean values. They are typed as
BooleanDefaultTrueorBooleanDefaultFalse. In this case it is default true which means by default, the new transaction will be signed and processed withoutsignActionbeing required.Could you explain the concept of "accept delayed broadcast," how to use it, and its intended use cases?
By default new transactions are broadcast by a background process, that is the createAction call will likely return before the transaction has been broadcast to the bitcoin network. In some cases the application is willing to wait for an initial broadcast attempt to be made in which case createAction (or signAction) doesn't return until that happens.
What does "trust self" mean in this context, and how does it relate to the transaction?
Setting trustSelf: 'known' allows for significantly slimmer Beefs to be sent from the wallet to the backend servers.
When prior outputs are included as inputs in a new transaction, the server already knows they are valid. Thus the Beef sent to the server for the new transaction can omit raw transaction and proof data for these outputs.What is the purpose of the knownTxids parameter?
When the wallet returns a Beef to the user, if there are transactions whose validity is already known to the application layer, they can include these txids in knownTxids to avoid redundant data being returned by the backend services or wallet.
4.5 What does noSendChange do, and in which scenarios would it be useful?
noSendChange is critical when building batches of transactions. To create a batch, use the noSend flag on all of the createAction calls and set sendWith to all previously created actions for the final action. noSendChain allows for effecient change management when transactions will be sent as a batch. The change from the previous noSend action starts the funding for the next noSend action.
If randomizeOutputs is set to true, should the wallet shuffle the user-provided outputs array?
no
Response Values
(Related to 4.5) Could you clarify the purpose of noSendChange?
Forward the noSendChange response from on noSend createAction call to the next through the noSendChange option.
How do the statuses unproven and sending differ?
Unproven transactions are known to the bitcoin network but have not been mined into a block yet and therefore lack merkle proof data. A transaction is completed once it has merkle proof data. A transaction with status 'sending' has not yet been successfully broadcast to the bitcoin network. Typically 'sending' status doesn't last long, but due to network outages, service failures or other issues it may take time for the bitcoin network to accept the transaction.
How should signable transactions be used in this endpoint, given that it does not allow providing a pre-prepared BEEF structure?
The signableTransaction response allows the user to call
Transaction.fromAtomicBEEF(signableTransaction)to obtain an unsigned parsed bitcoin transaction. The reason for this is to allow the user to directly control the signing of specific user provided inputs. Once this is done, the signedunlockingScriptsare included in a subsequent call to signAction to complete the original createAction and process the new transaction.It seems that the signable transaction structure might need to be extensible. For example:
How can a user indicate that one input requires a key with a certain security level and another requires a different level?
The parsed unsigned
Transactioncan have unlockingScriptTemplates assigned to specific inputs such that when thesign()method is called the correctunlockingScriptvalues will be computed for those inputs.If a new derivation scheme is introduced, would this API need updating, and how would that affect backward compatibility?
Create a new unlockingScriptTemplate for the derivation scheme and use it.
If a wallet still uses an older derivation scheme (like BIP32), how can this API accommodate it so that more wallets can conform without enforcing a full migration to a new scheme?
Use a BIP32 unlockingScriptTemplate.
Error Handling
Are there recommended validation steps that wallets should perform before processing a request, and what are best practices for handling malformed inputs?
This is a weak point in the current specification that we are moving to improve through the NinjaWallet proposed work.
For invalid inputs we propose to standardize on an object with at least the following properties being thrown as an error:{ isError: true, name: 'WERR_INVALID_PARAMETER', message: <a string detailing the specifc parameter and the nature of the error> }Are there specific error codes for missing or incorrect parameters?
This area of the specification needs work...
Further clarification has been added to BRC-100: #82
- locked and limited conversation to collaborators
on Dec 15, 2024
BRC ID
100
Discussion
I would like clarification regarding the
createActionmethod defined in BRC-100. The questions primarily concern the "Method Calls" specification section.description, what occurs if the user provides only this parameter?inputBEEFandinputsare provided?BEEFdata, can I use this endpoint, or should I use a different one?inputDescriptionfield within the input array?inputDescriptionfield required?descriptioninstead ofinputDescription?basketis not provided? Is there a default categorization?signAndProcessis not provided?knownTxidsparameter?noSendChangedo, and in which scenarios would it be useful?randomizeOutputsis set totrue, should the wallet shuffle the user-provided outputs array?noSendChange?unprovenandsendingdiffer?BEEFstructure?