Today we made a major step forward in the MyZubster Gateway β Tari network integration, focusing on the infrastructure required to move MYZ withdrawals from a simulated development flow toward real on-chain Tari payouts.
This was not just a configuration change. We went deep into the Tari codebase, traced the wallet transaction flow, identified the correct API layer, inspected the protobuf definitions, verified the transaction types, and prepared the environment required to build and run the Tari wallet.
Hereβs a detailed breakdown of what was done today.
ποΈ 1. Auditing the Existing MyZubster Payout Service
We started from the existing:
MyZubsterGateway/tari_payout.js
The current service already provides the basic payout abstraction:
transferToAddress()
transfer IDs
user IDs
destination addresses
payout amounts
transfer status
transaction IDs
failure handling
user transfer history
The service also includes a development simulation mode.
Previously, if a real Tari wallet was not configured, the system generated a simulated transaction ID such as:
tari_tx_sim_...
This was useful during development, but it obviously cannot be used for actual withdrawals.
The important discovery was that the current implementation attempted to communicate with Tari using:
POST /transfer
through Axios.
That assumption needed to be validated against the actual Tari wallet implementation.
π 2. Going Directly Into the Tari Source Code
Instead of guessing how the wallet works, we inspected the Tari repository directly.
We located the relevant applications:
applications/minotari_console_wallet
applications/minotari_node
applications/minotari_mcp_wallet
applications/minotari_mcp_node
The most important component for our use case is:
applications/minotari_console_wallet
This is the wallet application responsible for handling outgoing transactions.
From there, we traced the wallet's gRPC implementation.
β‘ 3. Identifying the Real Wallet API: gRPC
One of the biggest findings today was that the Tari wallet exposes its transaction functionality through gRPC.
The relevant implementation is:
applications/minotari_console_wallet/src/grpc/wallet_grpc_server.rs
We found the wallet server implementation and, more importantly, the actual:
Transfer
RPC.
The corresponding protobuf definition is located at:
applications/minotari_app_grpc/proto/wallet.proto
This gives us the actual contract between the MyZubster Gateway and the Tari wallet.
So the architecture is being changed conceptually from:
MyZubster
β
HTTP /transfer
β
Tari
to:
MyZubster
β
gRPC TransferRequest
β
Tari Console Wallet
β
Tari Network
This is a much more accurate integration with the Tari wallet we're actually running.
π‘ 4. Inspecting TransferRequest
We found the actual protobuf definition:
message TransferRequest {
repeated PaymentRecipient recipients = 1;
bool single_tx = 2;
}
This is important because it confirms that Tari supports sending funds to one or multiple recipients through the wallet API.
The actual recipient object is:
message PaymentRecipient {
string address = 1;
uint64 amount = 2;
uint64 fee_per_gram = 3;
PaymentType payment_type = 5;
bytes raw_payment_id = 6;
UserPaymentId user_payment_id = 7;
}
This gives us everything required for the MyZubster withdrawal flow:
destination Tari address
amount
fee configuration
payment type
optional payment metadata
π° 5. Confirming Tari's Unit of Account
Another important implementation detail we verified today is the amount denomination.
The Tari protobuf explicitly defines:
amount
as a value in microTari.
Therefore:
1 Tari = 1,000,000 microTari
This is particularly important for MyZubster because the Gateway currently works with MYZ amounts.
The conversion layer therefore needs to be explicit and deterministic rather than relying on implicit floating-point conversion.
For example:
1 MYZ β 1,000,000 microTari
assuming the MyZubster economic model defines MYZ with that exact Tari-denominated conversion.
This will be handled carefully in the final payout implementation to avoid rounding or precision problems.
π 6. Investigating Tari Payment Types
We also inspected the supported payment types.
Tari currently exposes:
STANDARD_MIMBLEWIMBLE = 0
ONE_SIDED = 1
ONE_SIDED_TO_STEALTH_ADDRESS = 2
The wallet implementation showed that the newer one-sided stealth mechanism is directly supported by the transaction service.
We found code paths such as:
send_one_sided_transaction(...)
and:
send_one_sided_to_stealth_address_transaction(...)
This is important because a MyZubster withdrawal does not require an interactive sender/receiver transaction flow.
For the production payout system, we'll be able to select the appropriate Tari payment mechanism based on the address and wallet requirements.
π§ 7. Inspecting the Actual Transfer Implementation
We went further than simply finding the protobuf.
We inspected the actual Rust implementation around the wallet's transfer() method.
The wallet:
receives the gRPC request;
validates the Tari address;
processes the recipient;
validates the payment type;
constructs the payment ID;
calls the appropriate transaction service;
obtains the transaction ID;
performs broadcast/confirmation handling;
returns a TransferResult.
This is extremely useful because it means the Gateway doesn't need to reproduce Tari's transaction construction logic.
The Tari wallet remains responsible for:
UTXO selection
transaction construction
fees
signing
transaction service interaction
broadcasting
The MyZubster Gateway should remain responsible for:
withdrawal validation
user/account balance management
payout authorization
transaction tracking
business logic
reconciliation
That separation is exactly what we want.
π 8. Understanding TransferResult
We also inspected the response structure:
message TransferResult {
string address = 1;
uint64 transaction_id = 2;
bool is_success = 3;
string failure_message = 4;
TransactionInfo transaction_info = 5;
}
This gives us a much better foundation for the MyZubster payout state machine.
Instead of simply assuming:
HTTP 200 = payout successful
we can distinguish between:
requested
β
wallet accepted
β
transaction created
β
broadcast
β
confirmed
β
completed
and failure states.
This is particularly important for financial operations.
π 9. Investigating gRPC Authentication
We also traced Tari's gRPC authentication implementation.
The relevant type is:
GrpcAuthentication
located in:
base_layer/common_types/src/grpc_authentication.rs
The wallet configuration exposes:
grpc_authentication
and the gRPC server creates:
ServerAuthenticationInterceptor
before accepting requests.
We also found the console wallet configuration example:
gRPC authentication method
grpc_authentication = { username = "admin", password = "xxxx" }
This means the final Gateway integration must not blindly expose the wallet's gRPC endpoint.
Authentication needs to be configured deliberately, especially if the Gateway and wallet are not isolated on the same private host/network.
π 10. Identifying the gRPC Endpoint
We traced how the console wallet obtains its gRPC listener address.
The wallet accepts:
MINOTARI_WALLET_GRPC_ADDRESS
and the configuration eventually reaches:
run_grpc(...)
where the address is converted and passed into:
serve_with_shutdown(...)
The configuration examples point to:
18143
for the console wallet gRPC interface.
So our intended local architecture is:
MyZubster Gateway
β
β gRPC
βΌ
127.0.0.1:18143
β
βΌ
Minotari Console Wallet
This keeps the wallet API local rather than unnecessarily exposing it publicly.
π¦ 11. Preparing the Tari Build Environment
The server did not initially have the Rust toolchain installed.
We installed Rust using rustup.
The environment now reports:
rustc 1.97.1
cargo 1.97.1
We then attempted to build:
minotari_console_wallet
using:
cargo build -p minotari_console_wallet --release
π§ 12. Resolving the Missing C Toolchain
The first compilation attempt revealed another environment issue:
error: linker x86_64-linux-gnu-gcc not found
This wasn't a Tari source-code problem.
The machine simply didn't have the required system compiler/linker available.
We installed the necessary build tooling and verified:
/usr/bin/gcc
/usr/bin/x86_64-linux-gnu-gcc
with:
gcc 13.3.0
The correct cross-target linker is now available.
π¦ 13. Tari Dependencies Successfully Downloaded
After fixing the build environment, Cargo was able to resolve and download the Tari dependency tree.
The build downloaded more than:
600 crates
with approximately:
57 MB
of Rust dependencies.
This included major components such as:
tonic
hyper
libc
sqlite
git2
hickory
zerocopy
and many others required by the Tari ecosystem.
The build is now progressing through the actual compilation stage.
π§ͺ 14. Current Build Status
The current command is:
cargo build -p minotari_console_wallet --release
The initial failure caused by the missing linker has been addressed.
The next milestone is obtaining:
target/release/minotari_console_wallet
Once that binary exists, we can move from source-code investigation into actual runtime testing.
π 15. Next Phase: Live gRPC Testing
The next phase will be to start the console wallet with gRPC enabled and verify:
127.0.0.1:18143
is listening.
We'll then test the actual Transfer RPC independently from MyZubster.
The goal is to prove this path first:
gRPC client
β
TransferRequest
β
Tari Wallet
β
TransferResult
before connecting the production withdrawal system.
This gives us a much safer development process.
πΈ 16. Next Phase: Rebuilding tari_payout.js
Once the wallet RPC is proven, we'll update the MyZubster Gateway.
The current concept:
axios.post(${TARI_WALLET_URL}/transfer, ...)
will be replaced with a proper Tari gRPC client.
The Gateway will construct a request equivalent to:
TransferRequest
βββ PaymentRecipient
βββ address
βββ amount
βββ fee_per_gram
βββ payment_type
βββ payment_id
The response will then be mapped into MyZubster's internal payout state.
π§Ύ 17. Improving Transaction Tracking
The existing MyZubster service already has a useful foundation:
transferId
userId
address
amount
status
createdAt
txId
networkTxId
We'll preserve that architecture while making the transaction ID come from the real Tari wallet.
The eventual lifecycle will look more like:
pending
β
submitted
β
sent
β
broadcast
β
confirmed
β
completed
with explicit failure handling.
This is significantly safer than treating the initial RPC response as proof that the transaction has permanently settled.
π‘οΈ 18. Production Safety
Another important principle from today's work is that real withdrawals should not be enabled simply because the RPC call works.
Before production payouts, we'll need to validate:
Tari wallet connectivity
wallet synchronization
available balance
correct network
destination address validation
amount conversion
fee handling
transaction IDs
broadcast status
confirmation handling
duplicate withdrawal protection
failure/retry behavior
authentication
wallet endpoint exposure
logging and reconciliation
Financial transaction infrastructure needs these checks before moving from development to production.
π― The Architecture We're Building
The final architecture is shaping up as:
MYZUBSTER
β
βΌ
Withdrawal Request
β
βΌ
MyZubster Gateway
β
βββββββββββ΄ββββββββββ
β β
βΌ βΌ
Balance / Ledger Payout Service
β
βΌ
Tari gRPC Client
β
βΌ
Minotari Console Wallet
:18143
β
βΌ
Tari Transaction
β
βΌ
Tari Network
β
βΌ
Recipient
This gives us a clean separation between the MyZubster business layer and the Tari blockchain layer.
π What Comes Next
The immediate priorities are:
- Finish the Tari wallet compilation
cargo build -p minotari_console_wallet --release
- Start the wallet
with the correct network and gRPC configuration.
- Verify gRPC
127.0.0.1:18143
- Execute a controlled test transaction
using the actual TransferRequest.
- Implement the Node.js gRPC client
inside tari_payout.js.
Connect it to MyZubster withdrawals.
Add robust transaction state and confirmation tracking.
π₯ Summary
Today was primarily about understanding the real Tari architecture and building the correct foundation, rather than rushing directly into production transactions.
We moved from an assumed REST integration to the actual Tari wallet gRPC architecture, traced the transaction implementation down to the Rust wallet service, identified the protobuf contract, verified payment types and microTari denomination, investigated authentication, identified the wallet gRPC endpoint, and prepared the server with the Rust and C build toolchains required to compile Tari.
The result is a much clearer and more reliable path toward real MYZ β Tari withdrawals.
The next major milestone is simple:
Get the Tari wallet running, connect to gRPC, execute the first controlled real transfer, and then wire that transaction path into the MyZubster Gateway.
MyZubster Γ Tari β real blockchain payouts are getting closer. π
Top comments (0)