feat: Add standalone wallet tracking for deal monitoring without private keys - #550

Merged
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker
Jul 23, 2025
Merged

feat: Add standalone wallet tracking for deal monitoring without private keys#550
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker

Conversation

@parkan

@parkanparkan commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

This bundles together two major enhancements:

  • feat: allow importing wallets by actor id for tracking of non-owned wallets, for tracking 3rd party deals or insecure environments
  • perf: improve dealtracker performance ~25x at comparable CPU and RAM usage, resulting in <10 minute runtime n testing

Please see the two individual commits for details

@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from c904ff9 to 697782cCompareJuly 15, 2025 13:57
@parkan

parkan commented Jul 15, 2025

Copy link
Copy Markdown
CollaboratorAuthor

ok, I see we ended up with conflicts, this is one downside to the new migrations strategy, resolved

I also noticed that the CI may not have been updated to use the new migrations system (go generate is failing)

staticcheck seems to be having issues again as well, though I really hope this is just a GH actions fluke (checks pass locally)

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok we've been very casual about breaking the build on develop, perhaps worth discussing this as this PR should be fully green (as function of my changes)

PrivateKey: privateKey,
WalletType: model.UserWallet,
}
} else if isTrackOnly {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion declined to keep changeset minimal and targeted, since other work is being done on other wallet types (SP wallets)

ContactInfo string `json:"contactInfo"`
Location string `json:"location"`
PrivateKey string `json:"privateKey,omitempty" table:"-"`
WalletType WalletType `gorm:"default:'UserWallet'" json:"walletType"`

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion delcined since this follows style pattern of the migrations and commits introducing that were merged to develop despite raised checks


// extractClientFromRawJSON quickly extracts the client ID from raw JSON without full parsing
func (p *BatchParser) extractClientFromRawJSON(data []byte) (string, bool) {
// Use gjson for fast client extraction from raw JSON

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might actually need to fix this since the handling was restructured


// shouldProcessDeal quickly checks if a deal should be processed based on client ID
func (p *BatchParser) shouldProcessDeal(data []byte) bool {
// Fast client check using gjson

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know this was a rule and my local checks did not flag, ok can do

}

// parseDeal parses a full deal from raw JSON data
func (p *BatchParser) parseDeal(data []byte) (*ParsedDeal, error) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibid

})
}

func TestDealStateStreamFromHttpRequest_Compressed(t *testing.T) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by the batch parser test

@Sankara-Jefferson
Sankara-Jefferson self-requested a review July 16, 2025 00:46
@Sankara-Jefferson

Sankara-Jefferson commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@parkan
Unit and E2E Tests

  • The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.
  • Documentation: Add or update main docs and API references for wallet tracking, including usage examples and options.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan I think the track option you just added should also support the additional metadata (name, contact, location. etc.) FFWD could use it to track all deal states of their grantees' deals on-chain.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan, It looks like your branch was created from develop on July 11, 2025, after the deal template integration was merged. However, there have been additional changes merged into develop since then that are not included in your PR.

Before merging, please:

  • Rebase your branch onto the latest develop to ensure all recent changes are included and avoid any missing features or regressions.
  • Resolve any conflicts and verify that all critical features (such as wallet balance) remain intact after the rebase.
  • Once this is done, I’ll proceed with the merge. Let me know if you have any questions or need help with the rebase process.

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok sure I can rebase migrations again (see my above comment) etc as well as add support for contact metadata and such, easy

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

also I forcefully disagree with this:

The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.

the e2e tests are highly comprehensive and equal or better to anything in the codebase

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

I will take a look at them once its rebased. It very possible I missed them due to the corruption.

parkan added 3 commits July 23, 2025 19:58
- Replace jstream with custom streaming parser using gjson
- Add fast-path client filtering (50x+ faster for non-matching deals)
- Implement parallel worker architecture (4 workers) for deal processing
- Add batch processing to reduce database contention
- Stream 40GB dataset in 4MB chunks to avoid memory issues
- Achieve 3-4x throughput improvement with reduced context switches
Changes:
- Custom ParsedDeal type and BatchParser for efficient processing
- Memory-efficient streaming with gjson (allows efficient single field extraction) for JSON parsing
- Worker goroutines for parallel deal processing
- Configurable batch sizes (default 100 deals/batch)
- Better CPU utilization through reduced map[string]interface{} overhead"
…ate keys
Implements TrackedWallet functionality to enable deal tracking for arbitrary
client wallets without requiring private key import, enhancing security for
deal monitoring use cases.
```bash
$ singularity wallet track f01131298
$ singularity run deal-tracker [...]
```
Deals will be tracked as if they were made by an owned wallet.
**Model & Migration:**
- Add TrackedWallet to WalletType enum alongside UserWallet and SPWallet
- Create database migration (202507091100) for TrackedWallet support
- Resolve ActorID to address via Lotus API to satisfy unique constraints
**CLI Interface:**
- Add `singularity wallet track <actor_id>` command
- Integrates with existing wallet management workflow
- Uses default Lotus API endpoint with graceful fallback
**Implementation Details:**
- TrackedWallet stores ActorID for deal matching (deal tracker unchanged)
- Resolves ActorID to address using Filecoin.StateAccountKey API call
- No private key storage for TrackedWallet type
- Validates ActorID format (must start with f0/t0)
**Error Handling & UX:**
- User-friendly error messages for common mistakes:
- Storage provider ActorIDs: "is a storage provider, not a client wallet"
- Non-existent ActorIDs: "does not exist on the network"
- Invalid actor types: "is not a client wallet"
- Graceful handling of Lotus API connectivity issues
**Testing:**
- Comprehensive unit tests with mocked Lotus client
- E2E tests with real Lotus API calls (skipped if network unavailable)
- Error scenario validation for all edge cases
- Tests multiple TrackedWallet creation and unique constraint handling
Enables minimal deal-tracker deployments for monitoring client wallets without
exposing private keys, e.g.:
- Third-party deal monitoring services
- Read-only tracking of client deal activity
- Insecure deployments which may leak private keys
Fully backward compatible - existing UserWallet and SPWallet functionality
unchanged. Deal tracker continues matching on ActorID as before. Attempting
to sign or send messages from a tracked-only wallet will fail in the same
way as with an SPWallet.
- Removing a wallet will not remove tracked deals (but stop updating them).
This is as per existing implementation and needs PM input to address.
- Error when trying to sign messages with a non-user wallet is not helpful.
(ibid)
@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from 697782c to 940d3e8CompareJuly 23, 2025 18:00
@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok, the conflicts should be resolved now

the longer the develop branch languishes in this state the more difficult the conflict resolution will get, of course

@Sankara-JeffersonSankara-Jefferson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!

@Sankara-Jefferson
Sankara-Jefferson merged commit 36d4df7 into developJul 23, 2025
7 of 13 checks passed
@Sankara-Jefferson
Sankara-Jefferson deleted the feat/standalone-dealtracker branch July 23, 2025 18:55
parkan added a commit that referenced this pull request Oct 22, 2025
…ate keys (#550)
This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!
The failing CIs will be fixed on separate PRs.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@parkan@Sankara-Jefferson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: Add standalone wallet tracking for deal monitoring without private keys - #550

Merged
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker
Jul 23, 2025
Merged

feat: Add standalone wallet tracking for deal monitoring without private keys#550
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker

Conversation

@parkan

@parkanparkan commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

This bundles together two major enhancements:

  • feat: allow importing wallets by actor id for tracking of non-owned wallets, for tracking 3rd party deals or insecure environments
  • perf: improve dealtracker performance ~25x at comparable CPU and RAM usage, resulting in <10 minute runtime n testing

Please see the two individual commits for details

@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from c904ff9 to 697782cCompareJuly 15, 2025 13:57
@parkan

parkan commented Jul 15, 2025

Copy link
Copy Markdown
CollaboratorAuthor

ok, I see we ended up with conflicts, this is one downside to the new migrations strategy, resolved

I also noticed that the CI may not have been updated to use the new migrations system (go generate is failing)

staticcheck seems to be having issues again as well, though I really hope this is just a GH actions fluke (checks pass locally)

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok we've been very casual about breaking the build on develop, perhaps worth discussing this as this PR should be fully green (as function of my changes)

PrivateKey: privateKey,
WalletType: model.UserWallet,
}
} else if isTrackOnly {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion declined to keep changeset minimal and targeted, since other work is being done on other wallet types (SP wallets)

ContactInfo string `json:"contactInfo"`
Location string `json:"location"`
PrivateKey string `json:"privateKey,omitempty" table:"-"`
WalletType WalletType `gorm:"default:'UserWallet'" json:"walletType"`

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion delcined since this follows style pattern of the migrations and commits introducing that were merged to develop despite raised checks


// extractClientFromRawJSON quickly extracts the client ID from raw JSON without full parsing
func (p *BatchParser) extractClientFromRawJSON(data []byte) (string, bool) {
// Use gjson for fast client extraction from raw JSON

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might actually need to fix this since the handling was restructured


// shouldProcessDeal quickly checks if a deal should be processed based on client ID
func (p *BatchParser) shouldProcessDeal(data []byte) bool {
// Fast client check using gjson

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know this was a rule and my local checks did not flag, ok can do

}

// parseDeal parses a full deal from raw JSON data
func (p *BatchParser) parseDeal(data []byte) (*ParsedDeal, error) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibid

})
}

func TestDealStateStreamFromHttpRequest_Compressed(t *testing.T) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by the batch parser test

@Sankara-Jefferson
Sankara-Jefferson self-requested a review July 16, 2025 00:46
@Sankara-Jefferson

Sankara-Jefferson commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@parkan
Unit and E2E Tests

  • The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.
  • Documentation: Add or update main docs and API references for wallet tracking, including usage examples and options.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan I think the track option you just added should also support the additional metadata (name, contact, location. etc.) FFWD could use it to track all deal states of their grantees' deals on-chain.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan, It looks like your branch was created from develop on July 11, 2025, after the deal template integration was merged. However, there have been additional changes merged into develop since then that are not included in your PR.

Before merging, please:

  • Rebase your branch onto the latest develop to ensure all recent changes are included and avoid any missing features or regressions.
  • Resolve any conflicts and verify that all critical features (such as wallet balance) remain intact after the rebase.
  • Once this is done, I’ll proceed with the merge. Let me know if you have any questions or need help with the rebase process.

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok sure I can rebase migrations again (see my above comment) etc as well as add support for contact metadata and such, easy

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

also I forcefully disagree with this:

The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.

the e2e tests are highly comprehensive and equal or better to anything in the codebase

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

I will take a look at them once its rebased. It very possible I missed them due to the corruption.

parkan added 3 commits July 23, 2025 19:58
- Replace jstream with custom streaming parser using gjson
- Add fast-path client filtering (50x+ faster for non-matching deals)
- Implement parallel worker architecture (4 workers) for deal processing
- Add batch processing to reduce database contention
- Stream 40GB dataset in 4MB chunks to avoid memory issues
- Achieve 3-4x throughput improvement with reduced context switches
Changes:
- Custom ParsedDeal type and BatchParser for efficient processing
- Memory-efficient streaming with gjson (allows efficient single field extraction) for JSON parsing
- Worker goroutines for parallel deal processing
- Configurable batch sizes (default 100 deals/batch)
- Better CPU utilization through reduced map[string]interface{} overhead"
…ate keys
Implements TrackedWallet functionality to enable deal tracking for arbitrary
client wallets without requiring private key import, enhancing security for
deal monitoring use cases.
```bash
$ singularity wallet track f01131298
$ singularity run deal-tracker [...]
```
Deals will be tracked as if they were made by an owned wallet.
**Model & Migration:**
- Add TrackedWallet to WalletType enum alongside UserWallet and SPWallet
- Create database migration (202507091100) for TrackedWallet support
- Resolve ActorID to address via Lotus API to satisfy unique constraints
**CLI Interface:**
- Add `singularity wallet track <actor_id>` command
- Integrates with existing wallet management workflow
- Uses default Lotus API endpoint with graceful fallback
**Implementation Details:**
- TrackedWallet stores ActorID for deal matching (deal tracker unchanged)
- Resolves ActorID to address using Filecoin.StateAccountKey API call
- No private key storage for TrackedWallet type
- Validates ActorID format (must start with f0/t0)
**Error Handling & UX:**
- User-friendly error messages for common mistakes:
- Storage provider ActorIDs: "is a storage provider, not a client wallet"
- Non-existent ActorIDs: "does not exist on the network"
- Invalid actor types: "is not a client wallet"
- Graceful handling of Lotus API connectivity issues
**Testing:**
- Comprehensive unit tests with mocked Lotus client
- E2E tests with real Lotus API calls (skipped if network unavailable)
- Error scenario validation for all edge cases
- Tests multiple TrackedWallet creation and unique constraint handling
Enables minimal deal-tracker deployments for monitoring client wallets without
exposing private keys, e.g.:
- Third-party deal monitoring services
- Read-only tracking of client deal activity
- Insecure deployments which may leak private keys
Fully backward compatible - existing UserWallet and SPWallet functionality
unchanged. Deal tracker continues matching on ActorID as before. Attempting
to sign or send messages from a tracked-only wallet will fail in the same
way as with an SPWallet.
- Removing a wallet will not remove tracked deals (but stop updating them).
This is as per existing implementation and needs PM input to address.
- Error when trying to sign messages with a non-user wallet is not helpful.
(ibid)
@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from 697782c to 940d3e8CompareJuly 23, 2025 18:00
@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok, the conflicts should be resolved now

the longer the develop branch languishes in this state the more difficult the conflict resolution will get, of course

@Sankara-JeffersonSankara-Jefferson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!

@Sankara-Jefferson
Sankara-Jefferson merged commit 36d4df7 into developJul 23, 2025
7 of 13 checks passed
@Sankara-Jefferson
Sankara-Jefferson deleted the feat/standalone-dealtracker branch July 23, 2025 18:55
parkan added a commit that referenced this pull request Oct 22, 2025
…ate keys (#550)
This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!
The failing CIs will be fixed on separate PRs.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@parkan@Sankara-Jefferson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Add standalone wallet tracking for deal monitoring without private keys - #550

Merged
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker
Jul 23, 2025
Merged

feat: Add standalone wallet tracking for deal monitoring without private keys#550
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker

Conversation

@parkan

@parkanparkan commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

This bundles together two major enhancements:

  • feat: allow importing wallets by actor id for tracking of non-owned wallets, for tracking 3rd party deals or insecure environments
  • perf: improve dealtracker performance ~25x at comparable CPU and RAM usage, resulting in <10 minute runtime n testing

Please see the two individual commits for details

@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from c904ff9 to 697782cCompareJuly 15, 2025 13:57
@parkan

parkan commented Jul 15, 2025

Copy link
Copy Markdown
CollaboratorAuthor

ok, I see we ended up with conflicts, this is one downside to the new migrations strategy, resolved

I also noticed that the CI may not have been updated to use the new migrations system (go generate is failing)

staticcheck seems to be having issues again as well, though I really hope this is just a GH actions fluke (checks pass locally)

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok we've been very casual about breaking the build on develop, perhaps worth discussing this as this PR should be fully green (as function of my changes)

PrivateKey: privateKey,
WalletType: model.UserWallet,
}
} else if isTrackOnly {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion declined to keep changeset minimal and targeted, since other work is being done on other wallet types (SP wallets)

ContactInfo string `json:"contactInfo"`
Location string `json:"location"`
PrivateKey string `json:"privateKey,omitempty" table:"-"`
WalletType WalletType `gorm:"default:'UserWallet'" json:"walletType"`

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion delcined since this follows style pattern of the migrations and commits introducing that were merged to develop despite raised checks


// extractClientFromRawJSON quickly extracts the client ID from raw JSON without full parsing
func (p *BatchParser) extractClientFromRawJSON(data []byte) (string, bool) {
// Use gjson for fast client extraction from raw JSON

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might actually need to fix this since the handling was restructured


// shouldProcessDeal quickly checks if a deal should be processed based on client ID
func (p *BatchParser) shouldProcessDeal(data []byte) bool {
// Fast client check using gjson

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know this was a rule and my local checks did not flag, ok can do

}

// parseDeal parses a full deal from raw JSON data
func (p *BatchParser) parseDeal(data []byte) (*ParsedDeal, error) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibid

})
}

func TestDealStateStreamFromHttpRequest_Compressed(t *testing.T) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by the batch parser test

@Sankara-Jefferson
Sankara-Jefferson self-requested a review July 16, 2025 00:46
@Sankara-Jefferson

Sankara-Jefferson commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@parkan
Unit and E2E Tests

  • The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.
  • Documentation: Add or update main docs and API references for wallet tracking, including usage examples and options.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan I think the track option you just added should also support the additional metadata (name, contact, location. etc.) FFWD could use it to track all deal states of their grantees' deals on-chain.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan, It looks like your branch was created from develop on July 11, 2025, after the deal template integration was merged. However, there have been additional changes merged into develop since then that are not included in your PR.

Before merging, please:

  • Rebase your branch onto the latest develop to ensure all recent changes are included and avoid any missing features or regressions.
  • Resolve any conflicts and verify that all critical features (such as wallet balance) remain intact after the rebase.
  • Once this is done, I’ll proceed with the merge. Let me know if you have any questions or need help with the rebase process.

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok sure I can rebase migrations again (see my above comment) etc as well as add support for contact metadata and such, easy

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

also I forcefully disagree with this:

The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.

the e2e tests are highly comprehensive and equal or better to anything in the codebase

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

I will take a look at them once its rebased. It very possible I missed them due to the corruption.

parkan added 3 commits July 23, 2025 19:58
- Replace jstream with custom streaming parser using gjson
- Add fast-path client filtering (50x+ faster for non-matching deals)
- Implement parallel worker architecture (4 workers) for deal processing
- Add batch processing to reduce database contention
- Stream 40GB dataset in 4MB chunks to avoid memory issues
- Achieve 3-4x throughput improvement with reduced context switches
Changes:
- Custom ParsedDeal type and BatchParser for efficient processing
- Memory-efficient streaming with gjson (allows efficient single field extraction) for JSON parsing
- Worker goroutines for parallel deal processing
- Configurable batch sizes (default 100 deals/batch)
- Better CPU utilization through reduced map[string]interface{} overhead"
…ate keys
Implements TrackedWallet functionality to enable deal tracking for arbitrary
client wallets without requiring private key import, enhancing security for
deal monitoring use cases.
```bash
$ singularity wallet track f01131298
$ singularity run deal-tracker [...]
```
Deals will be tracked as if they were made by an owned wallet.
**Model & Migration:**
- Add TrackedWallet to WalletType enum alongside UserWallet and SPWallet
- Create database migration (202507091100) for TrackedWallet support
- Resolve ActorID to address via Lotus API to satisfy unique constraints
**CLI Interface:**
- Add `singularity wallet track <actor_id>` command
- Integrates with existing wallet management workflow
- Uses default Lotus API endpoint with graceful fallback
**Implementation Details:**
- TrackedWallet stores ActorID for deal matching (deal tracker unchanged)
- Resolves ActorID to address using Filecoin.StateAccountKey API call
- No private key storage for TrackedWallet type
- Validates ActorID format (must start with f0/t0)
**Error Handling & UX:**
- User-friendly error messages for common mistakes:
- Storage provider ActorIDs: "is a storage provider, not a client wallet"
- Non-existent ActorIDs: "does not exist on the network"
- Invalid actor types: "is not a client wallet"
- Graceful handling of Lotus API connectivity issues
**Testing:**
- Comprehensive unit tests with mocked Lotus client
- E2E tests with real Lotus API calls (skipped if network unavailable)
- Error scenario validation for all edge cases
- Tests multiple TrackedWallet creation and unique constraint handling
Enables minimal deal-tracker deployments for monitoring client wallets without
exposing private keys, e.g.:
- Third-party deal monitoring services
- Read-only tracking of client deal activity
- Insecure deployments which may leak private keys
Fully backward compatible - existing UserWallet and SPWallet functionality
unchanged. Deal tracker continues matching on ActorID as before. Attempting
to sign or send messages from a tracked-only wallet will fail in the same
way as with an SPWallet.
- Removing a wallet will not remove tracked deals (but stop updating them).
This is as per existing implementation and needs PM input to address.
- Error when trying to sign messages with a non-user wallet is not helpful.
(ibid)
@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from 697782c to 940d3e8CompareJuly 23, 2025 18:00
@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok, the conflicts should be resolved now

the longer the develop branch languishes in this state the more difficult the conflict resolution will get, of course

@Sankara-JeffersonSankara-Jefferson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!

@Sankara-Jefferson
Sankara-Jefferson merged commit 36d4df7 into developJul 23, 2025
7 of 13 checks passed
@Sankara-Jefferson
Sankara-Jefferson deleted the feat/standalone-dealtracker branch July 23, 2025 18:55
parkan added a commit that referenced this pull request Oct 22, 2025
…ate keys (#550)
This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!
The failing CIs will be fixed on separate PRs.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@parkan@Sankara-Jefferson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Add standalone wallet tracking for deal monitoring without private keys - #550

Merged
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker
Jul 23, 2025
Merged

feat: Add standalone wallet tracking for deal monitoring without private keys#550
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker

Conversation

@parkan

@parkanparkan commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

This bundles together two major enhancements:

  • feat: allow importing wallets by actor id for tracking of non-owned wallets, for tracking 3rd party deals or insecure environments
  • perf: improve dealtracker performance ~25x at comparable CPU and RAM usage, resulting in <10 minute runtime n testing

Please see the two individual commits for details

@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from c904ff9 to 697782cCompareJuly 15, 2025 13:57
@parkan

parkan commented Jul 15, 2025

Copy link
Copy Markdown
CollaboratorAuthor

ok, I see we ended up with conflicts, this is one downside to the new migrations strategy, resolved

I also noticed that the CI may not have been updated to use the new migrations system (go generate is failing)

staticcheck seems to be having issues again as well, though I really hope this is just a GH actions fluke (checks pass locally)

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok we've been very casual about breaking the build on develop, perhaps worth discussing this as this PR should be fully green (as function of my changes)

PrivateKey: privateKey,
WalletType: model.UserWallet,
}
} else if isTrackOnly {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion declined to keep changeset minimal and targeted, since other work is being done on other wallet types (SP wallets)

ContactInfo string `json:"contactInfo"`
Location string `json:"location"`
PrivateKey string `json:"privateKey,omitempty" table:"-"`
WalletType WalletType `gorm:"default:'UserWallet'" json:"walletType"`

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion delcined since this follows style pattern of the migrations and commits introducing that were merged to develop despite raised checks


// extractClientFromRawJSON quickly extracts the client ID from raw JSON without full parsing
func (p *BatchParser) extractClientFromRawJSON(data []byte) (string, bool) {
// Use gjson for fast client extraction from raw JSON

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might actually need to fix this since the handling was restructured


// shouldProcessDeal quickly checks if a deal should be processed based on client ID
func (p *BatchParser) shouldProcessDeal(data []byte) bool {
// Fast client check using gjson

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know this was a rule and my local checks did not flag, ok can do

}

// parseDeal parses a full deal from raw JSON data
func (p *BatchParser) parseDeal(data []byte) (*ParsedDeal, error) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibid

})
}

func TestDealStateStreamFromHttpRequest_Compressed(t *testing.T) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by the batch parser test

@Sankara-Jefferson
Sankara-Jefferson self-requested a review July 16, 2025 00:46
@Sankara-Jefferson

Sankara-Jefferson commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@parkan
Unit and E2E Tests

  • The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.
  • Documentation: Add or update main docs and API references for wallet tracking, including usage examples and options.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan I think the track option you just added should also support the additional metadata (name, contact, location. etc.) FFWD could use it to track all deal states of their grantees' deals on-chain.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan, It looks like your branch was created from develop on July 11, 2025, after the deal template integration was merged. However, there have been additional changes merged into develop since then that are not included in your PR.

Before merging, please:

  • Rebase your branch onto the latest develop to ensure all recent changes are included and avoid any missing features or regressions.
  • Resolve any conflicts and verify that all critical features (such as wallet balance) remain intact after the rebase.
  • Once this is done, I’ll proceed with the merge. Let me know if you have any questions or need help with the rebase process.

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok sure I can rebase migrations again (see my above comment) etc as well as add support for contact metadata and such, easy

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

also I forcefully disagree with this:

The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.

the e2e tests are highly comprehensive and equal or better to anything in the codebase

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

I will take a look at them once its rebased. It very possible I missed them due to the corruption.

parkan added 3 commits July 23, 2025 19:58
- Replace jstream with custom streaming parser using gjson
- Add fast-path client filtering (50x+ faster for non-matching deals)
- Implement parallel worker architecture (4 workers) for deal processing
- Add batch processing to reduce database contention
- Stream 40GB dataset in 4MB chunks to avoid memory issues
- Achieve 3-4x throughput improvement with reduced context switches
Changes:
- Custom ParsedDeal type and BatchParser for efficient processing
- Memory-efficient streaming with gjson (allows efficient single field extraction) for JSON parsing
- Worker goroutines for parallel deal processing
- Configurable batch sizes (default 100 deals/batch)
- Better CPU utilization through reduced map[string]interface{} overhead"
…ate keys
Implements TrackedWallet functionality to enable deal tracking for arbitrary
client wallets without requiring private key import, enhancing security for
deal monitoring use cases.
```bash
$ singularity wallet track f01131298
$ singularity run deal-tracker [...]
```
Deals will be tracked as if they were made by an owned wallet.
**Model & Migration:**
- Add TrackedWallet to WalletType enum alongside UserWallet and SPWallet
- Create database migration (202507091100) for TrackedWallet support
- Resolve ActorID to address via Lotus API to satisfy unique constraints
**CLI Interface:**
- Add `singularity wallet track <actor_id>` command
- Integrates with existing wallet management workflow
- Uses default Lotus API endpoint with graceful fallback
**Implementation Details:**
- TrackedWallet stores ActorID for deal matching (deal tracker unchanged)
- Resolves ActorID to address using Filecoin.StateAccountKey API call
- No private key storage for TrackedWallet type
- Validates ActorID format (must start with f0/t0)
**Error Handling & UX:**
- User-friendly error messages for common mistakes:
- Storage provider ActorIDs: "is a storage provider, not a client wallet"
- Non-existent ActorIDs: "does not exist on the network"
- Invalid actor types: "is not a client wallet"
- Graceful handling of Lotus API connectivity issues
**Testing:**
- Comprehensive unit tests with mocked Lotus client
- E2E tests with real Lotus API calls (skipped if network unavailable)
- Error scenario validation for all edge cases
- Tests multiple TrackedWallet creation and unique constraint handling
Enables minimal deal-tracker deployments for monitoring client wallets without
exposing private keys, e.g.:
- Third-party deal monitoring services
- Read-only tracking of client deal activity
- Insecure deployments which may leak private keys
Fully backward compatible - existing UserWallet and SPWallet functionality
unchanged. Deal tracker continues matching on ActorID as before. Attempting
to sign or send messages from a tracked-only wallet will fail in the same
way as with an SPWallet.
- Removing a wallet will not remove tracked deals (but stop updating them).
This is as per existing implementation and needs PM input to address.
- Error when trying to sign messages with a non-user wallet is not helpful.
(ibid)
@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from 697782c to 940d3e8CompareJuly 23, 2025 18:00
@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok, the conflicts should be resolved now

the longer the develop branch languishes in this state the more difficult the conflict resolution will get, of course

@Sankara-JeffersonSankara-Jefferson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!

@Sankara-Jefferson
Sankara-Jefferson merged commit 36d4df7 into developJul 23, 2025
7 of 13 checks passed
@Sankara-Jefferson
Sankara-Jefferson deleted the feat/standalone-dealtracker branch July 23, 2025 18:55
parkan added a commit that referenced this pull request Oct 22, 2025
…ate keys (#550)
This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!
The failing CIs will be fixed on separate PRs.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@parkan@Sankara-Jefferson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: Add standalone wallet tracking for deal monitoring without private keys - #550

Merged
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker
Jul 23, 2025
Merged

feat: Add standalone wallet tracking for deal monitoring without private keys#550
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker

Conversation

@parkan

@parkanparkan commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

This bundles together two major enhancements:

  • feat: allow importing wallets by actor id for tracking of non-owned wallets, for tracking 3rd party deals or insecure environments
  • perf: improve dealtracker performance ~25x at comparable CPU and RAM usage, resulting in <10 minute runtime n testing

Please see the two individual commits for details

@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from c904ff9 to 697782cCompareJuly 15, 2025 13:57
@parkan

parkan commented Jul 15, 2025

Copy link
Copy Markdown
CollaboratorAuthor

ok, I see we ended up with conflicts, this is one downside to the new migrations strategy, resolved

I also noticed that the CI may not have been updated to use the new migrations system (go generate is failing)

staticcheck seems to be having issues again as well, though I really hope this is just a GH actions fluke (checks pass locally)

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok we've been very casual about breaking the build on develop, perhaps worth discussing this as this PR should be fully green (as function of my changes)

PrivateKey: privateKey,
WalletType: model.UserWallet,
}
} else if isTrackOnly {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion declined to keep changeset minimal and targeted, since other work is being done on other wallet types (SP wallets)

ContactInfo string `json:"contactInfo"`
Location string `json:"location"`
PrivateKey string `json:"privateKey,omitempty" table:"-"`
WalletType WalletType `gorm:"default:'UserWallet'" json:"walletType"`

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion delcined since this follows style pattern of the migrations and commits introducing that were merged to develop despite raised checks


// extractClientFromRawJSON quickly extracts the client ID from raw JSON without full parsing
func (p *BatchParser) extractClientFromRawJSON(data []byte) (string, bool) {
// Use gjson for fast client extraction from raw JSON

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might actually need to fix this since the handling was restructured


// shouldProcessDeal quickly checks if a deal should be processed based on client ID
func (p *BatchParser) shouldProcessDeal(data []byte) bool {
// Fast client check using gjson

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know this was a rule and my local checks did not flag, ok can do

}

// parseDeal parses a full deal from raw JSON data
func (p *BatchParser) parseDeal(data []byte) (*ParsedDeal, error) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibid

})
}

func TestDealStateStreamFromHttpRequest_Compressed(t *testing.T) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by the batch parser test

@Sankara-Jefferson
Sankara-Jefferson self-requested a review July 16, 2025 00:46
@Sankara-Jefferson

Sankara-Jefferson commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@parkan
Unit and E2E Tests

  • The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.
  • Documentation: Add or update main docs and API references for wallet tracking, including usage examples and options.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan I think the track option you just added should also support the additional metadata (name, contact, location. etc.) FFWD could use it to track all deal states of their grantees' deals on-chain.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan, It looks like your branch was created from develop on July 11, 2025, after the deal template integration was merged. However, there have been additional changes merged into develop since then that are not included in your PR.

Before merging, please:

  • Rebase your branch onto the latest develop to ensure all recent changes are included and avoid any missing features or regressions.
  • Resolve any conflicts and verify that all critical features (such as wallet balance) remain intact after the rebase.
  • Once this is done, I’ll proceed with the merge. Let me know if you have any questions or need help with the rebase process.

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok sure I can rebase migrations again (see my above comment) etc as well as add support for contact metadata and such, easy

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

also I forcefully disagree with this:

The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.

the e2e tests are highly comprehensive and equal or better to anything in the codebase

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

I will take a look at them once its rebased. It very possible I missed them due to the corruption.

parkan added 3 commits July 23, 2025 19:58
- Replace jstream with custom streaming parser using gjson
- Add fast-path client filtering (50x+ faster for non-matching deals)
- Implement parallel worker architecture (4 workers) for deal processing
- Add batch processing to reduce database contention
- Stream 40GB dataset in 4MB chunks to avoid memory issues
- Achieve 3-4x throughput improvement with reduced context switches
Changes:
- Custom ParsedDeal type and BatchParser for efficient processing
- Memory-efficient streaming with gjson (allows efficient single field extraction) for JSON parsing
- Worker goroutines for parallel deal processing
- Configurable batch sizes (default 100 deals/batch)
- Better CPU utilization through reduced map[string]interface{} overhead"
…ate keys
Implements TrackedWallet functionality to enable deal tracking for arbitrary
client wallets without requiring private key import, enhancing security for
deal monitoring use cases.
```bash
$ singularity wallet track f01131298
$ singularity run deal-tracker [...]
```
Deals will be tracked as if they were made by an owned wallet.
**Model & Migration:**
- Add TrackedWallet to WalletType enum alongside UserWallet and SPWallet
- Create database migration (202507091100) for TrackedWallet support
- Resolve ActorID to address via Lotus API to satisfy unique constraints
**CLI Interface:**
- Add `singularity wallet track <actor_id>` command
- Integrates with existing wallet management workflow
- Uses default Lotus API endpoint with graceful fallback
**Implementation Details:**
- TrackedWallet stores ActorID for deal matching (deal tracker unchanged)
- Resolves ActorID to address using Filecoin.StateAccountKey API call
- No private key storage for TrackedWallet type
- Validates ActorID format (must start with f0/t0)
**Error Handling & UX:**
- User-friendly error messages for common mistakes:
- Storage provider ActorIDs: "is a storage provider, not a client wallet"
- Non-existent ActorIDs: "does not exist on the network"
- Invalid actor types: "is not a client wallet"
- Graceful handling of Lotus API connectivity issues
**Testing:**
- Comprehensive unit tests with mocked Lotus client
- E2E tests with real Lotus API calls (skipped if network unavailable)
- Error scenario validation for all edge cases
- Tests multiple TrackedWallet creation and unique constraint handling
Enables minimal deal-tracker deployments for monitoring client wallets without
exposing private keys, e.g.:
- Third-party deal monitoring services
- Read-only tracking of client deal activity
- Insecure deployments which may leak private keys
Fully backward compatible - existing UserWallet and SPWallet functionality
unchanged. Deal tracker continues matching on ActorID as before. Attempting
to sign or send messages from a tracked-only wallet will fail in the same
way as with an SPWallet.
- Removing a wallet will not remove tracked deals (but stop updating them).
This is as per existing implementation and needs PM input to address.
- Error when trying to sign messages with a non-user wallet is not helpful.
(ibid)
@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from 697782c to 940d3e8CompareJuly 23, 2025 18:00
@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok, the conflicts should be resolved now

the longer the develop branch languishes in this state the more difficult the conflict resolution will get, of course

@Sankara-JeffersonSankara-Jefferson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!

@Sankara-Jefferson
Sankara-Jefferson merged commit 36d4df7 into developJul 23, 2025
7 of 13 checks passed
@Sankara-Jefferson
Sankara-Jefferson deleted the feat/standalone-dealtracker branch July 23, 2025 18:55
parkan added a commit that referenced this pull request Oct 22, 2025
…ate keys (#550)
This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!
The failing CIs will be fixed on separate PRs.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@parkan@Sankara-Jefferson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Add standalone wallet tracking for deal monitoring without private keys - #550

Merged
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker
Jul 23, 2025
Merged

feat: Add standalone wallet tracking for deal monitoring without private keys#550
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker

Conversation

@parkan

@parkanparkan commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

This bundles together two major enhancements:

  • feat: allow importing wallets by actor id for tracking of non-owned wallets, for tracking 3rd party deals or insecure environments
  • perf: improve dealtracker performance ~25x at comparable CPU and RAM usage, resulting in <10 minute runtime n testing

Please see the two individual commits for details

@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from c904ff9 to 697782cCompareJuly 15, 2025 13:57
@parkan

parkan commented Jul 15, 2025

Copy link
Copy Markdown
CollaboratorAuthor

ok, I see we ended up with conflicts, this is one downside to the new migrations strategy, resolved

I also noticed that the CI may not have been updated to use the new migrations system (go generate is failing)

staticcheck seems to be having issues again as well, though I really hope this is just a GH actions fluke (checks pass locally)

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok we've been very casual about breaking the build on develop, perhaps worth discussing this as this PR should be fully green (as function of my changes)

PrivateKey: privateKey,
WalletType: model.UserWallet,
}
} else if isTrackOnly {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion declined to keep changeset minimal and targeted, since other work is being done on other wallet types (SP wallets)

ContactInfo string `json:"contactInfo"`
Location string `json:"location"`
PrivateKey string `json:"privateKey,omitempty" table:"-"`
WalletType WalletType `gorm:"default:'UserWallet'" json:"walletType"`

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion delcined since this follows style pattern of the migrations and commits introducing that were merged to develop despite raised checks


// extractClientFromRawJSON quickly extracts the client ID from raw JSON without full parsing
func (p *BatchParser) extractClientFromRawJSON(data []byte) (string, bool) {
// Use gjson for fast client extraction from raw JSON

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might actually need to fix this since the handling was restructured


// shouldProcessDeal quickly checks if a deal should be processed based on client ID
func (p *BatchParser) shouldProcessDeal(data []byte) bool {
// Fast client check using gjson

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know this was a rule and my local checks did not flag, ok can do

}

// parseDeal parses a full deal from raw JSON data
func (p *BatchParser) parseDeal(data []byte) (*ParsedDeal, error) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibid

})
}

func TestDealStateStreamFromHttpRequest_Compressed(t *testing.T) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by the batch parser test

@Sankara-Jefferson
Sankara-Jefferson self-requested a review July 16, 2025 00:46
@Sankara-Jefferson

Sankara-Jefferson commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@parkan
Unit and E2E Tests

  • The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.
  • Documentation: Add or update main docs and API references for wallet tracking, including usage examples and options.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan I think the track option you just added should also support the additional metadata (name, contact, location. etc.) FFWD could use it to track all deal states of their grantees' deals on-chain.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan, It looks like your branch was created from develop on July 11, 2025, after the deal template integration was merged. However, there have been additional changes merged into develop since then that are not included in your PR.

Before merging, please:

  • Rebase your branch onto the latest develop to ensure all recent changes are included and avoid any missing features or regressions.
  • Resolve any conflicts and verify that all critical features (such as wallet balance) remain intact after the rebase.
  • Once this is done, I’ll proceed with the merge. Let me know if you have any questions or need help with the rebase process.

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok sure I can rebase migrations again (see my above comment) etc as well as add support for contact metadata and such, easy

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

also I forcefully disagree with this:

The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.

the e2e tests are highly comprehensive and equal or better to anything in the codebase

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

I will take a look at them once its rebased. It very possible I missed them due to the corruption.

parkan added 3 commits July 23, 2025 19:58
- Replace jstream with custom streaming parser using gjson
- Add fast-path client filtering (50x+ faster for non-matching deals)
- Implement parallel worker architecture (4 workers) for deal processing
- Add batch processing to reduce database contention
- Stream 40GB dataset in 4MB chunks to avoid memory issues
- Achieve 3-4x throughput improvement with reduced context switches
Changes:
- Custom ParsedDeal type and BatchParser for efficient processing
- Memory-efficient streaming with gjson (allows efficient single field extraction) for JSON parsing
- Worker goroutines for parallel deal processing
- Configurable batch sizes (default 100 deals/batch)
- Better CPU utilization through reduced map[string]interface{} overhead"
…ate keys
Implements TrackedWallet functionality to enable deal tracking for arbitrary
client wallets without requiring private key import, enhancing security for
deal monitoring use cases.
```bash
$ singularity wallet track f01131298
$ singularity run deal-tracker [...]
```
Deals will be tracked as if they were made by an owned wallet.
**Model & Migration:**
- Add TrackedWallet to WalletType enum alongside UserWallet and SPWallet
- Create database migration (202507091100) for TrackedWallet support
- Resolve ActorID to address via Lotus API to satisfy unique constraints
**CLI Interface:**
- Add `singularity wallet track <actor_id>` command
- Integrates with existing wallet management workflow
- Uses default Lotus API endpoint with graceful fallback
**Implementation Details:**
- TrackedWallet stores ActorID for deal matching (deal tracker unchanged)
- Resolves ActorID to address using Filecoin.StateAccountKey API call
- No private key storage for TrackedWallet type
- Validates ActorID format (must start with f0/t0)
**Error Handling & UX:**
- User-friendly error messages for common mistakes:
- Storage provider ActorIDs: "is a storage provider, not a client wallet"
- Non-existent ActorIDs: "does not exist on the network"
- Invalid actor types: "is not a client wallet"
- Graceful handling of Lotus API connectivity issues
**Testing:**
- Comprehensive unit tests with mocked Lotus client
- E2E tests with real Lotus API calls (skipped if network unavailable)
- Error scenario validation for all edge cases
- Tests multiple TrackedWallet creation and unique constraint handling
Enables minimal deal-tracker deployments for monitoring client wallets without
exposing private keys, e.g.:
- Third-party deal monitoring services
- Read-only tracking of client deal activity
- Insecure deployments which may leak private keys
Fully backward compatible - existing UserWallet and SPWallet functionality
unchanged. Deal tracker continues matching on ActorID as before. Attempting
to sign or send messages from a tracked-only wallet will fail in the same
way as with an SPWallet.
- Removing a wallet will not remove tracked deals (but stop updating them).
This is as per existing implementation and needs PM input to address.
- Error when trying to sign messages with a non-user wallet is not helpful.
(ibid)
@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from 697782c to 940d3e8CompareJuly 23, 2025 18:00
@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok, the conflicts should be resolved now

the longer the develop branch languishes in this state the more difficult the conflict resolution will get, of course

@Sankara-JeffersonSankara-Jefferson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!

@Sankara-Jefferson
Sankara-Jefferson merged commit 36d4df7 into developJul 23, 2025
7 of 13 checks passed
@Sankara-Jefferson
Sankara-Jefferson deleted the feat/standalone-dealtracker branch July 23, 2025 18:55
parkan added a commit that referenced this pull request Oct 22, 2025
…ate keys (#550)
This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!
The failing CIs will be fixed on separate PRs.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@parkan@Sankara-Jefferson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: Add standalone wallet tracking for deal monitoring without private keys - #550

Merged
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker
Jul 23, 2025
Merged

feat: Add standalone wallet tracking for deal monitoring without private keys#550
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker

Conversation

@parkan

@parkanparkan commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

This bundles together two major enhancements:

  • feat: allow importing wallets by actor id for tracking of non-owned wallets, for tracking 3rd party deals or insecure environments
  • perf: improve dealtracker performance ~25x at comparable CPU and RAM usage, resulting in <10 minute runtime n testing

Please see the two individual commits for details

@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from c904ff9 to 697782cCompareJuly 15, 2025 13:57
@parkan

parkan commented Jul 15, 2025

Copy link
Copy Markdown
CollaboratorAuthor

ok, I see we ended up with conflicts, this is one downside to the new migrations strategy, resolved

I also noticed that the CI may not have been updated to use the new migrations system (go generate is failing)

staticcheck seems to be having issues again as well, though I really hope this is just a GH actions fluke (checks pass locally)

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok we've been very casual about breaking the build on develop, perhaps worth discussing this as this PR should be fully green (as function of my changes)

PrivateKey: privateKey,
WalletType: model.UserWallet,
}
} else if isTrackOnly {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion declined to keep changeset minimal and targeted, since other work is being done on other wallet types (SP wallets)

ContactInfo string `json:"contactInfo"`
Location string `json:"location"`
PrivateKey string `json:"privateKey,omitempty" table:"-"`
WalletType WalletType `gorm:"default:'UserWallet'" json:"walletType"`

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion delcined since this follows style pattern of the migrations and commits introducing that were merged to develop despite raised checks


// extractClientFromRawJSON quickly extracts the client ID from raw JSON without full parsing
func (p *BatchParser) extractClientFromRawJSON(data []byte) (string, bool) {
// Use gjson for fast client extraction from raw JSON

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might actually need to fix this since the handling was restructured


// shouldProcessDeal quickly checks if a deal should be processed based on client ID
func (p *BatchParser) shouldProcessDeal(data []byte) bool {
// Fast client check using gjson

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know this was a rule and my local checks did not flag, ok can do

}

// parseDeal parses a full deal from raw JSON data
func (p *BatchParser) parseDeal(data []byte) (*ParsedDeal, error) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibid

})
}

func TestDealStateStreamFromHttpRequest_Compressed(t *testing.T) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by the batch parser test

@Sankara-Jefferson
Sankara-Jefferson self-requested a review July 16, 2025 00:46
@Sankara-Jefferson

Sankara-Jefferson commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@parkan
Unit and E2E Tests

  • The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.
  • Documentation: Add or update main docs and API references for wallet tracking, including usage examples and options.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan I think the track option you just added should also support the additional metadata (name, contact, location. etc.) FFWD could use it to track all deal states of their grantees' deals on-chain.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan, It looks like your branch was created from develop on July 11, 2025, after the deal template integration was merged. However, there have been additional changes merged into develop since then that are not included in your PR.

Before merging, please:

  • Rebase your branch onto the latest develop to ensure all recent changes are included and avoid any missing features or regressions.
  • Resolve any conflicts and verify that all critical features (such as wallet balance) remain intact after the rebase.
  • Once this is done, I’ll proceed with the merge. Let me know if you have any questions or need help with the rebase process.

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok sure I can rebase migrations again (see my above comment) etc as well as add support for contact metadata and such, easy

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

also I forcefully disagree with this:

The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.

the e2e tests are highly comprehensive and equal or better to anything in the codebase

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

I will take a look at them once its rebased. It very possible I missed them due to the corruption.

parkan added 3 commits July 23, 2025 19:58
- Replace jstream with custom streaming parser using gjson
- Add fast-path client filtering (50x+ faster for non-matching deals)
- Implement parallel worker architecture (4 workers) for deal processing
- Add batch processing to reduce database contention
- Stream 40GB dataset in 4MB chunks to avoid memory issues
- Achieve 3-4x throughput improvement with reduced context switches
Changes:
- Custom ParsedDeal type and BatchParser for efficient processing
- Memory-efficient streaming with gjson (allows efficient single field extraction) for JSON parsing
- Worker goroutines for parallel deal processing
- Configurable batch sizes (default 100 deals/batch)
- Better CPU utilization through reduced map[string]interface{} overhead"
…ate keys
Implements TrackedWallet functionality to enable deal tracking for arbitrary
client wallets without requiring private key import, enhancing security for
deal monitoring use cases.
```bash
$ singularity wallet track f01131298
$ singularity run deal-tracker [...]
```
Deals will be tracked as if they were made by an owned wallet.
**Model & Migration:**
- Add TrackedWallet to WalletType enum alongside UserWallet and SPWallet
- Create database migration (202507091100) for TrackedWallet support
- Resolve ActorID to address via Lotus API to satisfy unique constraints
**CLI Interface:**
- Add `singularity wallet track <actor_id>` command
- Integrates with existing wallet management workflow
- Uses default Lotus API endpoint with graceful fallback
**Implementation Details:**
- TrackedWallet stores ActorID for deal matching (deal tracker unchanged)
- Resolves ActorID to address using Filecoin.StateAccountKey API call
- No private key storage for TrackedWallet type
- Validates ActorID format (must start with f0/t0)
**Error Handling & UX:**
- User-friendly error messages for common mistakes:
- Storage provider ActorIDs: "is a storage provider, not a client wallet"
- Non-existent ActorIDs: "does not exist on the network"
- Invalid actor types: "is not a client wallet"
- Graceful handling of Lotus API connectivity issues
**Testing:**
- Comprehensive unit tests with mocked Lotus client
- E2E tests with real Lotus API calls (skipped if network unavailable)
- Error scenario validation for all edge cases
- Tests multiple TrackedWallet creation and unique constraint handling
Enables minimal deal-tracker deployments for monitoring client wallets without
exposing private keys, e.g.:
- Third-party deal monitoring services
- Read-only tracking of client deal activity
- Insecure deployments which may leak private keys
Fully backward compatible - existing UserWallet and SPWallet functionality
unchanged. Deal tracker continues matching on ActorID as before. Attempting
to sign or send messages from a tracked-only wallet will fail in the same
way as with an SPWallet.
- Removing a wallet will not remove tracked deals (but stop updating them).
This is as per existing implementation and needs PM input to address.
- Error when trying to sign messages with a non-user wallet is not helpful.
(ibid)
@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from 697782c to 940d3e8CompareJuly 23, 2025 18:00
@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok, the conflicts should be resolved now

the longer the develop branch languishes in this state the more difficult the conflict resolution will get, of course

@Sankara-JeffersonSankara-Jefferson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!

@Sankara-Jefferson
Sankara-Jefferson merged commit 36d4df7 into developJul 23, 2025
7 of 13 checks passed
@Sankara-Jefferson
Sankara-Jefferson deleted the feat/standalone-dealtracker branch July 23, 2025 18:55
parkan added a commit that referenced this pull request Oct 22, 2025
…ate keys (#550)
This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!
The failing CIs will be fixed on separate PRs.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@parkan@Sankara-Jefferson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: Add standalone wallet tracking for deal monitoring without private keys - #550

Merged
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker
Jul 23, 2025
Merged

feat: Add standalone wallet tracking for deal monitoring without private keys#550
Sankara-Jefferson merged 3 commits into
developfrom
feat/standalone-dealtracker

Conversation

@parkan

@parkanparkan commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

This bundles together two major enhancements:

  • feat: allow importing wallets by actor id for tracking of non-owned wallets, for tracking 3rd party deals or insecure environments
  • perf: improve dealtracker performance ~25x at comparable CPU and RAM usage, resulting in <10 minute runtime n testing

Please see the two individual commits for details

@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from c904ff9 to 697782cCompareJuly 15, 2025 13:57
@parkan

parkan commented Jul 15, 2025

Copy link
Copy Markdown
CollaboratorAuthor

ok, I see we ended up with conflicts, this is one downside to the new migrations strategy, resolved

I also noticed that the CI may not have been updated to use the new migrations system (go generate is failing)

staticcheck seems to be having issues again as well, though I really hope this is just a GH actions fluke (checks pass locally)

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok we've been very casual about breaking the build on develop, perhaps worth discussing this as this PR should be fully green (as function of my changes)

PrivateKey: privateKey,
WalletType: model.UserWallet,
}
} else if isTrackOnly {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion declined to keep changeset minimal and targeted, since other work is being done on other wallet types (SP wallets)

ContactInfo string `json:"contactInfo"`
Location string `json:"location"`
PrivateKey string `json:"privateKey,omitempty" table:"-"`
WalletType WalletType `gorm:"default:'UserWallet'" json:"walletType"`

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gocritic suggestion delcined since this follows style pattern of the migrations and commits introducing that were merged to develop despite raised checks


// extractClientFromRawJSON quickly extracts the client ID from raw JSON without full parsing
func (p *BatchParser) extractClientFromRawJSON(data []byte) (string, bool) {
// Use gjson for fast client extraction from raw JSON

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might actually need to fix this since the handling was restructured


// shouldProcessDeal quickly checks if a deal should be processed based on client ID
func (p *BatchParser) shouldProcessDeal(data []byte) bool {
// Fast client check using gjson

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even know this was a rule and my local checks did not flag, ok can do

}

// parseDeal parses a full deal from raw JSON data
func (p *BatchParser) parseDeal(data []byte) (*ParsedDeal, error) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ibid

})
}

func TestDealStateStreamFromHttpRequest_Compressed(t *testing.T) {

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by the batch parser test

@Sankara-Jefferson
Sankara-Jefferson self-requested a review July 16, 2025 00:46
@Sankara-Jefferson

Sankara-Jefferson commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

@parkan
Unit and E2E Tests

  • The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.
  • Documentation: Add or update main docs and API references for wallet tracking, including usage examples and options.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan I think the track option you just added should also support the additional metadata (name, contact, location. etc.) FFWD could use it to track all deal states of their grantees' deals on-chain.

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

@parkan, It looks like your branch was created from develop on July 11, 2025, after the deal template integration was merged. However, there have been additional changes merged into develop since then that are not included in your PR.

Before merging, please:

  • Rebase your branch onto the latest develop to ensure all recent changes are included and avoid any missing features or regressions.
  • Resolve any conflicts and verify that all critical features (such as wallet balance) remain intact after the rebase.
  • Once this is done, I’ll proceed with the merge. Let me know if you have any questions or need help with the rebase process.

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok sure I can rebase migrations again (see my above comment) etc as well as add support for contact metadata and such, easy

@parkan

Copy link
Copy Markdown
CollaboratorAuthor

also I forcefully disagree with this:

The only test files found and run were for dealtracker logic. No unit or E2E test files for the new wallet tracking CLI (cmd/wallet/track.go) or handler (handler/wallet/track_e2e_test.go) were found. Ensure comprehensive unit and E2E tests exist for wallet tracking commands and handlers.

the e2e tests are highly comprehensive and equal or better to anything in the codebase

@Sankara-Jefferson

Copy link
Copy Markdown
Contributor

I will take a look at them once its rebased. It very possible I missed them due to the corruption.

parkan added 3 commits July 23, 2025 19:58
- Replace jstream with custom streaming parser using gjson
- Add fast-path client filtering (50x+ faster for non-matching deals)
- Implement parallel worker architecture (4 workers) for deal processing
- Add batch processing to reduce database contention
- Stream 40GB dataset in 4MB chunks to avoid memory issues
- Achieve 3-4x throughput improvement with reduced context switches
Changes:
- Custom ParsedDeal type and BatchParser for efficient processing
- Memory-efficient streaming with gjson (allows efficient single field extraction) for JSON parsing
- Worker goroutines for parallel deal processing
- Configurable batch sizes (default 100 deals/batch)
- Better CPU utilization through reduced map[string]interface{} overhead"
…ate keys
Implements TrackedWallet functionality to enable deal tracking for arbitrary
client wallets without requiring private key import, enhancing security for
deal monitoring use cases.
```bash
$ singularity wallet track f01131298
$ singularity run deal-tracker [...]
```
Deals will be tracked as if they were made by an owned wallet.
**Model & Migration:**
- Add TrackedWallet to WalletType enum alongside UserWallet and SPWallet
- Create database migration (202507091100) for TrackedWallet support
- Resolve ActorID to address via Lotus API to satisfy unique constraints
**CLI Interface:**
- Add `singularity wallet track <actor_id>` command
- Integrates with existing wallet management workflow
- Uses default Lotus API endpoint with graceful fallback
**Implementation Details:**
- TrackedWallet stores ActorID for deal matching (deal tracker unchanged)
- Resolves ActorID to address using Filecoin.StateAccountKey API call
- No private key storage for TrackedWallet type
- Validates ActorID format (must start with f0/t0)
**Error Handling & UX:**
- User-friendly error messages for common mistakes:
- Storage provider ActorIDs: "is a storage provider, not a client wallet"
- Non-existent ActorIDs: "does not exist on the network"
- Invalid actor types: "is not a client wallet"
- Graceful handling of Lotus API connectivity issues
**Testing:**
- Comprehensive unit tests with mocked Lotus client
- E2E tests with real Lotus API calls (skipped if network unavailable)
- Error scenario validation for all edge cases
- Tests multiple TrackedWallet creation and unique constraint handling
Enables minimal deal-tracker deployments for monitoring client wallets without
exposing private keys, e.g.:
- Third-party deal monitoring services
- Read-only tracking of client deal activity
- Insecure deployments which may leak private keys
Fully backward compatible - existing UserWallet and SPWallet functionality
unchanged. Deal tracker continues matching on ActorID as before. Attempting
to sign or send messages from a tracked-only wallet will fail in the same
way as with an SPWallet.
- Removing a wallet will not remove tracked deals (but stop updating them).
This is as per existing implementation and needs PM input to address.
- Error when trying to sign messages with a non-user wallet is not helpful.
(ibid)
@parkan
parkanforce-pushed the feat/standalone-dealtracker branch from 697782c to 940d3e8CompareJuly 23, 2025 18:00
@parkan

Copy link
Copy Markdown
CollaboratorAuthor

ok, the conflicts should be resolved now

the longer the develop branch languishes in this state the more difficult the conflict resolution will get, of course

@Sankara-JeffersonSankara-Jefferson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!

@Sankara-Jefferson
Sankara-Jefferson merged commit 36d4df7 into developJul 23, 2025
7 of 13 checks passed
@Sankara-Jefferson
Sankara-Jefferson deleted the feat/standalone-dealtracker branch July 23, 2025 18:55
parkan added a commit that referenced this pull request Oct 22, 2025
…ate keys (#550)
This PR introduces tracked wallet support, allowing monitoring of wallets without private keys, and delivers major performance improvements to the deal tracker via streaming and batch processing. The implementation is robust, well-tested (unit and E2E), and thoroughly documented. Thanks for the valuable contribution—merging!
The failing CIs will be fixed on separate PRs.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@parkan@Sankara-Jefferson