mirror of
https://github.com/luxfi/bridge.git
synced 2026-09-24 00:26:46 +00:00
internal/mchain: - pickAddress for AddressTypeTON now derives the real v4r2 address from EDDSAPubKey when the keygen surfaces it (workchain=0 + DefaultSubwallet=698983191 + V4R2 code + pubkey → state_init.Hash). Falls back to the legacy SOL slot when the cluster hasn't yet emitted the Ed25519 pubkey, so existing mpcd deployments don't break. - mchain.Wallet now carries ECDSAPubKey + EDDSAPubKey so downstream consumers (release_pool, signing_driver) can drive chain-specific flows without re-querying mpcd. - New ton.go houses deriveTONAddressFromHex, delegating cell encoding to tonutils-go (same lib the txassembler depends on) so addresses surfaced at keygen time are bit-identical to those the txassembler rebuilds in state_init at first send. cmd/bridge/release_pool.go: - ReleasePoolEntry gains AddressType + ECDSAPubKey + EDDSAPubKey fields so the signing driver can route per-family. Legacy entries without these fields fall through to the EVM path (AddressType= empty equals "eth" via the dispatch default). cmd/bridge/balance_probe.go: - TON branch added to BalanceAt: GET <toncenter>/getAddressBalance, optional X-API-Key header from c.TONAPIKeys[network]. Returns *big.Int of nanoton. Same best-effort policy as the EVM path (probe failures log and skip rather than block signing). - TONBalanceURLs + TONAPIKeys maps populated by main.go from networks.yaml's per-network Broadcast block. cmd/bridge/signing_driver.go: - New tonAssembler field + SetTONAssembler setter mirroring SetAssembler. Dispatch in signOne now branches on mchain.AddressTypeFor(DestinationNetwork): TON → PreSignTON path (looks up the pool entry's EDDSAPubKey, builds the v4r2 unsigned body, computes the nanoton-unit gas pre-check, finalizes via FinalizeTONHex into base64 BOC); otherwise → EVM path (unchanged). - gasPrecheckTON: 0.05 TON gas floor for native transfers, 0.15 TON for jetton transfers (covers body value + forward TON + master call gas). Native transfers count the user amount against the release wallet; jetton transfers don't (the user value moves between jetton wallets, not out of ours). - tonAmountToNano + isTONNativeAsset helpers — same fixed-point float→big.Int approach as the EVM floatToWei to avoid IEEE noise. cmd/bridge/config.go: - Network gains an optional Broadcast block (URL + APIKey) so operators configure TON Center endpoints per-network in networks.yaml without flag plumbing. cmd/bridge/main.go: - TON assembler instantiated at startup and wired into the signing driver via SetTONAssembler. - Broadcast client picks up per-network sendBoc URLs + X-API-Keys from the new networks.yaml block. - Balance probe picks up per-network getAddressBalance URLs (derived from sendBoc by path-swap) + the same X-API-Keys.
62 lines
2.4 KiB
Go
62 lines
2.4 KiB
Go
package mchain
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
|
|
tonwallet "github.com/xssnick/tonutils-go/ton/wallet"
|
|
)
|
|
|
|
// ton.go: TON address derivation from an MPC-supplied Ed25519 pubkey.
|
|
//
|
|
// This file is the bridge-side mirror of the cluster's eventual TON
|
|
// keygen output. The standard TON v4r2 wallet address is:
|
|
//
|
|
// workchain = 0
|
|
// state_init = StateInit { code: V4R2_CODE, data: { seqno=0, subwallet=698983191, pubkey, plugins=null } }
|
|
// addr_data = sha256(StateInit_cell)
|
|
// raw_form = "0:" + hex(addr_data)
|
|
//
|
|
// We delegate the actual cell encoding + hash to tonutils-go (the
|
|
// canonical Go SDK that the txassembler also depends on) so the
|
|
// address we surface from a keygen is bit-identical to the address
|
|
// the txassembler builds the state_init for in PreSignTON.
|
|
//
|
|
// Why mchain owns this rather than txassembler:
|
|
// - Address selection happens at keygen time, before any tx
|
|
// assembler is involved (the bridge stores the address and shows
|
|
// it to the SDK + UI before the user ever deposits).
|
|
// - mchain is the canonical "given a keygen result, what's the
|
|
// receive address" function — putting this with the other
|
|
// pickAddress branches keeps that contract in one place.
|
|
|
|
// deriveTONAddressFromHex parses a hex-encoded Ed25519 public key
|
|
// (32 bytes) and returns the v4r2 raw address ("0:<hex>") for that
|
|
// pubkey. Returns an error on malformed hex or wrong length.
|
|
//
|
|
// Hex input may carry a 0x prefix (case-insensitive). Trimmed and
|
|
// decoded with encoding/hex.
|
|
//
|
|
// The "raw form" return is intentional — it's the lowest-common-
|
|
// denominator representation. Callers that want the user-friendly
|
|
// "EQ..." / "UQ..." form should pull the txassembler helpers
|
|
// (TONAddressFromPubKey + .String()).
|
|
func deriveTONAddressFromHex(pubkeyHex string) (string, error) {
|
|
pubkeyHex = strings.TrimPrefix(strings.TrimPrefix(pubkeyHex, "0x"), "0X")
|
|
pubkey, err := hex.DecodeString(pubkeyHex)
|
|
if err != nil {
|
|
return "", fmt.Errorf("mchain: ton: decode ed25519 pubkey hex: %w", err)
|
|
}
|
|
if len(pubkey) != ed25519.PublicKeySize {
|
|
return "", fmt.Errorf("mchain: ton: ed25519 pubkey wrong length: got %d want %d",
|
|
len(pubkey), ed25519.PublicKeySize)
|
|
}
|
|
addr, err := tonwallet.AddressFromPubKey(pubkey, tonwallet.V4R2, tonwallet.DefaultSubwallet)
|
|
if err != nil {
|
|
return "", fmt.Errorf("mchain: ton: derive v4r2 address: %w", err)
|
|
}
|
|
return addr.StringRaw(), nil
|
|
}
|