You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Transaction lifecycle events emitted by the non-EVM snaps could not be attributed to the flow that produced them. A Transaction Approved event, for example, is emitted by the classic wallet send, the dApp send, and the swap flow alike, and the payload carried only origin and no transaction_type, so nothing distinguished an in-app send from a signPsbt/sendTransfer confirmation.
This change distinguishes them by combining the two dimensions the schema already models: origin says who initiated the operation (metamask, a dApp origin, or cron), and transaction_type says what kind of operation it was, using the @metamask/keyring-apiTransactionType vocabulary (send, receive, swap, ...). Together they identify a flow: classic wallet send is metamask + send, a dApp send is <dapp> + send, and so on.
@metamask/snap-networks-utils — AnalyticsService now accepts an optional transactionType and emits it as transaction_type on Transaction Added, Transaction Approved, Transaction Rejected, and Transaction Submitted, matching the existing behaviour of Transaction Finalized. The property is omitted entirely when not supplied, so existing callers are unaffected.
@metamask/bitcoin-wallet-snap — threads transaction_type through the send and sign confirmations plus the broadcast/cron tracking events. The type is derived from the transaction by a new mapToTransactionType helper: a positive sent amount maps to send, otherwise receive. The signPsbt confirmation reports unknown, since an arbitrary PSBT cannot be classified.
The helper lives in entities/transaction.ts rather than handlers/mappings.ts on purpose: it is a pure function over an already-fetched transaction, and mappings.ts imports runtime values from @metamask/bitcoindevkit, which breaks the Jest CommonJS environment. mapToTransactionType uses only types from that package, and mapToTransaction now consumes it so the send/receive classification has a single source of truth.
Only Bitcoin is covered here; the other non-EVM snaps can adopt the same optional property incrementally.
References
Checklist
I've updated the test suite for new or updated code as appropriate
I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
Transaction lifecycle events could not be attributed to a specific flow
across non-EVM snaps. Distinguish them by combining `origin` (who
initiated the operation) with `transaction_type` (what kind of operation
it was), using the `@metamask/keyring-api` `TransactionType` vocabulary.
- `snap-networks-utils`: `AnalyticsService` now accepts an optional
`transactionType` and emits it as `transaction_type` on the
`Transaction Added`, `Transaction Approved`, `Transaction Rejected`,
and `Transaction Submitted` events, matching `Transaction Finalized`.
- `bitcoin-wallet-snap`: thread `transaction_type` through the send and
sign confirmations plus the broadcast/cron tracking events, deriving
it from the transaction with a new `mapToTransactionType` helper.
`applyUnconfirmedTx` takes ownership of the underlying wasm transaction,
so calling `mapToTransactionType(account, tx)` afterwards panicked with
"null pointer passed to rust" on every broadcast path (signPsbt,
broadcastPsbt, sendTransfer). Resolve the classification first and reuse
it for the submitted event.
Update the integration test assertions to include the new
`transaction_type` property, and ratchet the coverage thresholds.
`SecurityAlertDetectedEventProperties` and
`SecurityScanCompletedEventProperties` extended `TransactionEventProperties`,
so adding the optional `transactionType` there advertised it to the security
tracking methods as well. Those methods never emit the property, so a
type-valid caller value was silently discarded.
Introduce an `AccountEventProperties` base with the fields every account-scoped
event shares, and extend that from the security event types instead. The
transaction lifecycle types keep `transactionType`.
Replacing `export type * from './transaction'` with `export *` reintroduced a
wildcard value export, contrary to the explicit-export convention in
AGENTS.md. Name the new runtime symbol and the existing type individually so
the module surface stays explicit.
Adding the optional `transaction_type` field had inlined the shared payload
into all four lifecycle methods, so the common properties would have to be
changed in four places and could drift.
Restore the `#trackTransactionEvent` helper and build the payload, including
the conditional `transaction_type`, in that single place.
The new required parameter is missing from this public interface method's JSDoc, while the other parameters and neighboring tracking methods are fully documented. Add an @param entry so generated API documentation explains the argument.
The reason will be displayed to describe this comment to others. Learn more.
This transaction type could be categorized as Send when the PSBT spends the account's own inputs and otherwise unknown. (Applied to the 3 trackTransaction in this function)
A signPsbt confirmation always reported unknown, so a PSBT that spends
this account's inputs disagreed with the submitted event. Report send
when the account spends its own inputs, and keep unknown otherwise.
The strict enum rejected `Transaction['type']`, which the keyring API
types as a string literal union, so the Solana finalized event failed
type-checking. Use the template literal form, which accepts both the
enum members and that union while keeping the vocabulary constrained.
The entry referenced the stack base (#393) because the branch had no PR
number yet. Use the actual PR.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation
Transaction lifecycle events emitted by the non-EVM snaps could not be attributed to the flow that produced them. A
Transaction Approvedevent, for example, is emitted by the classic wallet send, the dApp send, and the swap flow alike, and the payload carried onlyoriginand notransaction_type, so nothing distinguished an in-app send from asignPsbt/sendTransferconfirmation.This change distinguishes them by combining the two dimensions the schema already models:
originsays who initiated the operation (metamask, a dApp origin, orcron), andtransaction_typesays what kind of operation it was, using the@metamask/keyring-apiTransactionTypevocabulary (send,receive,swap, ...). Together they identify a flow: classic wallet send ismetamask+send, a dApp send is<dapp>+send, and so on.@metamask/snap-networks-utils—AnalyticsServicenow accepts an optionaltransactionTypeand emits it astransaction_typeonTransaction Added,Transaction Approved,Transaction Rejected, andTransaction Submitted, matching the existing behaviour ofTransaction Finalized. The property is omitted entirely when not supplied, so existing callers are unaffected.@metamask/bitcoin-wallet-snap— threadstransaction_typethrough the send and sign confirmations plus the broadcast/cron tracking events. The type is derived from the transaction by a newmapToTransactionTypehelper: a positive sent amount maps tosend, otherwisereceive. ThesignPsbtconfirmation reportsunknown, since an arbitrary PSBT cannot be classified.The helper lives in
entities/transaction.tsrather thanhandlers/mappings.tson purpose: it is a pure function over an already-fetched transaction, andmappings.tsimports runtime values from@metamask/bitcoindevkit, which breaks the Jest CommonJS environment.mapToTransactionTypeuses only types from that package, andmapToTransactionnow consumes it so the send/receive classification has a single source of truth.Only Bitcoin is covered here; the other non-EVM snaps can adopt the same optional property incrementally.
References
Checklist