Skip to content

Add functionality to use cycles balance instead of CMC for topups#142

Open
patnorris wants to merge 5 commits intomainfrom
useBalanceForTopups
Open

Add functionality to use cycles balance instead of CMC for topups#142
patnorris wants to merge 5 commits intomainfrom
useBalanceForTopups

Conversation

@patnorris
Copy link
Copy Markdown
Contributor

No description provided.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new path for handling incoming ICP for mAIner top-ups/creation that can skip CMC conversion when the protocol’s cycles balance is above a buffer, and introduces optional disbursement of ICP to a team wallet in that “no conversion” scenario.

Changes:

  • Add an admin-controlled DISBURSE_FUNDS_TO_TEAM flag (toggle + getter).
  • Add team ICP disbursement flow (disburseIncomingFundsToTeam + transferToTeam).
  • Update handleIncomingFunds to (a) decide conversion based on Cycles.balance() vs PROTOCOL_CYCLES_BALANCE_BUFFER, and (b) add a bonus cycles amount when no conversion is performed, plus optional ICP disbursements.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
src/GameState/src/Main.mo Adds team-disbursement flag + transfer logic; updates incoming-funds handling to optionally skip CMC conversion and disburse ICP to treasury/team.
src/common/Types.mo Introduces IcpTransferArgsAccount for ledger transfers by account identifier.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/GameState/src/Main.mo
Comment on lines +509 to +515
let amountForTransfer : TokenLedger.Tokens = { e8s : Nat64 = Nat64.fromNat(amountToDisburse); };
D.print("GameState: disburseIncomingFundsToTeam - amountForTransfer: " # debug_show(amountForTransfer));
let TEAM_WALLET_ADDRESS : Blob = "5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783";
let transferArgs : Types.IcpTransferArgsAccount = {
amount : TokenLedger.Tokens = amountForTransfer;
to = TEAM_WALLET_ADDRESS;
};
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

TEAM_WALLET_ADDRESS is declared as a Blob but the literal provided is a hex text string; as a Motoko blob literal this becomes the ASCII bytes for those characters (length 64), not the 32-byte account identifier the ICP ledger transfer API expects. This will likely fail the transfer or send to the wrong destination. Decode the hex string into bytes (e.g., via a hex-decoder helper) and ensure the resulting blob is exactly 32 bytes.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback
the Principal module from the Motoko base library has the functions Principal.toBlob(principal) and Principal.toLedgerAccount(principal : Principal, subAccount : ?Blob) : Blob
https://docs.internetcomputer.org/motoko/base/Principal#function-toledgeraccount

The team wallet where the ICP should be sent to has the following info:
"ICP Native": 5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783
"ICRC-1": k3pwi-qyaaa-aaaab-acbrq-cai-uco74ta.ed7b8190c5714532b566097699c9715800000000000000000000000000000000

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Implemented in commit 61ad81e.

The team wallet destination is now derived with Principal.toLedgerAccount(Principal.fromText("k3pwi-qyaaa-aaaab-acbrq-cai"), null) instead of using an ASCII hex blob literal. I also added a guard in transferToTeam to verify the derived account matches the provided ICP Native account id (5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783) before any transfer proceeds.

Copy link
Copy Markdown
Contributor Author

@patnorris patnorris Apr 23, 2026

Choose a reason for hiding this comment

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

@copilot I don't think this will work as "k3pwi-qyaaa-aaaab-acbrq-cai" (as defined in
let TEAM_WALLET_PRINCIPAL : Principal = Principal.fromText("k3pwi-qyaaa-aaaab-acbrq-cai"); ) isn't the team's principal, the team just has a subaccount there, see the info above:
"ICP Native": 5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783
"ICRC-1": k3pwi-qyaaa-aaaab-acbrq-cai-uco74ta.ed7b8190c5714532b566097699c9715800000000000000000000000000000000

so sending the ICP to the account 5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783 is the way to go. Please update the code accordingly.

The Motoko base library has this function:
let blob = Text.encodeUtf8("Hello");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Updated in 6d4678a: team disbursement now targets the ICP Native account identifier directly by using the raw 32-byte account-id blob for 5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783 (no principal-based derivation). No UI changes to screenshot.

Comment thread src/GameState/src/Main.mo Outdated
Comment thread src/GameState/src/Main.mo Outdated
Comment on lines +579 to +588
let TEAM_WALLET_ADDRESS : Blob = "5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783";
D.print(
"Transferring "
# debug_show (args.amount)
# " tokens to TEAM_WALLET_ADDRESS "
# debug_show (TEAM_WALLET_ADDRESS)
);

let transferArgs : TokenLedger.TransferArgs = {
to : Blob = TEAM_WALLET_ADDRESS;
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

Same issue as above: TEAM_WALLET_ADDRESS is written as a hex text string but typed as Blob. For ledger transfer, to must be the raw 32-byte account identifier; using the ASCII bytes of the hex string will not represent the intended account.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback
use the same fix you'll implement above, based on this info again:
the Principal module from the Motoko base library has the functions Principal.toBlob(principal) and Principal.toLedgerAccount(principal : Principal, subAccount : ?Blob) : Blob
https://docs.internetcomputer.org/motoko/base/Principal#function-toledgeraccount

The team wallet where the ICP should be sent to has the following info:
"ICP Native": 5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783
"ICRC-1": k3pwi-qyaaa-aaaab-acbrq-cai-uco74ta.ed7b8190c5714532b566097699c9715800000000000000000000000000000000

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Handled already in 61ad81e: both team-transfer paths now use Principal.toLedgerAccount(Principal.fromText("k3pwi-qyaaa-aaaab-acbrq-cai"), null) and no longer use the hex-text blob literal. Backend-only change (no UI changes/screenshot).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

I don't think this will work as "k3pwi-qyaaa-aaaab-acbrq-cai" (as defined in
let TEAM_WALLET_PRINCIPAL : Principal = Principal.fromText("k3pwi-qyaaa-aaaab-acbrq-cai"); ) isn't the team's principal, the team just has a subaccount there, see the info above:
"ICP Native": 5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783
"ICRC-1": k3pwi-qyaaa-aaaab-acbrq-cai-uco74ta.ed7b8190c5714532b566097699c9715800000000000000000000000000000000

so sending the ICP to the account 5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783 is the way to go. Please update the code accordingly.

The Motoko base library has this function:
let blob = Text.encodeUtf8("Hello");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Implemented in 6d4678a: team transfers now use the explicit ICP Native account-id destination (5d9bb4f164022de0933d3b45eaf33f1902e9578a2f330a1301d531c42bebf783) via raw 32-byte blob bytes, not principal derivation/subaccount inference. No UI changes.

Comment thread src/GameState/src/Main.mo
Comment thread src/GameState/src/Main.mo
patnorris and others added 3 commits April 23, 2026 10:39
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/onicai/PoAIW/sessions/b2ca583e-6016-4447-85f9-b88632c99db5

Co-authored-by: patnorris <23037714+patnorris@users.noreply.github.com>
Agent-Logs-Url: https://github.com/onicai/PoAIW/sessions/b2ca583e-6016-4447-85f9-b88632c99db5

Co-authored-by: patnorris <23037714+patnorris@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI commented Apr 23, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • icp-api.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/_temp/ghcca-node/node/bin/mops install (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Sign up for free to 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.

3 participants