mirror of
https://github.com/luxfi/sdk.git
synced 2026-10-30 15:19:23 +00:00
github.com/luxfi/codec is gone from this module — no import, no call, no require. Nothing here marshals or unmarshals a transaction any more. WHY IT BROKE. codec deleted its jsonrpc subpackage (1b67d6a, "delete dead subpackages") while nine files imported it. It looked dead because the PUBLISHED [email protected] still ships it, so only a workspace build — which resolves codec from the local checkout — ever saw the break. THE WIRE. A tx already carries its own ZAP encoding, so the codec was re-deriving what the tx could hand over: txs.Codec.Marshal(txs.CodecVersion, &tx.Unsigned) -> tx.Unsigned.Bytes() txs.UnsignedBytes(tx.Unsigned) txs.Codec.Marshal(txs.CodecVersion, tx) -> tx.Initialize() txs.Codec.Unmarshal(txBytes, &tx) -> txs.Parse(txBytes) codec.Unmarshal(utxoBytes, &utxo) -> utxo.ParseUTXO(...) These are the same calls the node makes in txs.Tx.Sign. AddAllUTXOs no longer takes a codec.Manager, and SortTransferableOutputs / state.Sort / SortOperations no longer get one — upstream dropped the parameter. PARALLEL IMPLEMENTATIONS, DELETED. wallet/chain/{p,x} carried a second copy of the builder and signer beside the subpackages that already held them — p/signer_visitor.go and p/signer/visitor.go were both 399 lines of the same thing, and each defect had to be fixed twice. The flat files are gone; the package keeps the facade it already had in wallet_exports.go, which re-exports the subpackage. -4787 lines. wallet/chain/c is deleted. Its whole reason to exist was a codec.Manager scaffold for C-chain atomic-tx wire that nothing runs: NewWallet was passed nil for it, and the builder was commented out. The two symbols anything used move to where they are read — Account, a balance and a nonce off an EVM client, and EVMKeychain, the geth-address half of a keychain. Wallet no longer advertises a C() that only ever returned nil. ALIGNED. XAssetID -> UTXOAssetID, matching runtime.Runtime and netrunner, which already expected it. Keychain GetEth -> GetByEVM, EthAddrs -> EVMAddrs. warp UnsignedMessage and Message collapsed into one flat Message, so a signature is an Envelope rather than a second message type. netrunner's HealthResponse is read as a field: the getter form is protobuf, behind //go:build grpc, and the default build is ZAP-native. VERIFIED on a machine with the native libraries: go build ./... exits 0 with no codec require in go.mod, and go test ./... is 23 ok. Three packages still fail to build their tests — profiles, wallet/keychain, wallet/primary — and all three fail identically on the tree before this change: Consensus, VerifyHybridSecp256k1MLDSA and isXChainNotEnabled are referenced by tests and defined nowhere. evm failed there too and now passes.
138 lines
3.5 KiB
Go
138 lines
3.5 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// xfer is a simple tool to transfer LUX from X-Chain to P-Chain
|
|
// Usage: xfer -uri http://127.0.0.1:9630 -key ~/.lux/keys/mainnet-deployer.pk -amount 1000000000
|
|
// Or set PRIVATE_KEY env var (hex format) or MNEMONIC env var (24 words)
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/luxfi/constants"
|
|
"github.com/luxfi/ids"
|
|
"github.com/luxfi/sdk/keys"
|
|
"github.com/luxfi/sdk/wallet/primary"
|
|
lux "github.com/luxfi/utxo"
|
|
"github.com/luxfi/utxo/secp256k1fx"
|
|
)
|
|
|
|
func main() {
|
|
uri := flag.String("uri", "http://127.0.0.1:9630", "Node URI")
|
|
keyPath := flag.String("key", "", "Path to private key file (.pk hex format)")
|
|
amount := flag.Uint64("amount", 100000000, "Amount in nLUX to transfer (default 0.1 LUX)")
|
|
flag.Parse()
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
|
defer cancel()
|
|
|
|
// Load key from file or environment
|
|
keyBytes, err := keys.LoadKey(*keyPath)
|
|
if err != nil {
|
|
log.Fatalf("Failed to load key: %v", err)
|
|
}
|
|
|
|
// Create keychain
|
|
kc, err := keys.NewKeychain(keyBytes)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create keychain: %v", err)
|
|
}
|
|
kcAdapter := primary.NewKeychainAdapter(kc)
|
|
|
|
log.Printf("Using address: %s", kc.Addrs)
|
|
log.Printf("Node URI: %s", *uri)
|
|
log.Printf("Amount to transfer: %d nLUX", *amount)
|
|
|
|
// Create wallet
|
|
log.Println("Creating wallet...")
|
|
wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{
|
|
URI: *uri,
|
|
LUXKeychain: kcAdapter,
|
|
EthKeychain: kcAdapter,
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("Failed to create wallet: %v", err)
|
|
}
|
|
|
|
// Get P-Chain ID for export
|
|
pChainID := constants.PlatformChainID
|
|
|
|
// Get one of our addresses for the P-Chain output
|
|
addrs := kc.Addrs.List()
|
|
if len(addrs) == 0 {
|
|
log.Fatal("No addresses in keychain")
|
|
}
|
|
pAddr := addrs[0]
|
|
|
|
// Step 1: Export from X-Chain to P-Chain
|
|
log.Printf("Step 1: Exporting %d nLUX from X-Chain to P-Chain...", *amount)
|
|
|
|
// Get LUX asset ID from context
|
|
luxState, err := primary.FetchState(ctx, *uri, kc.Addrs)
|
|
if err != nil {
|
|
log.Fatalf("Failed to fetch state: %v", err)
|
|
}
|
|
luxAssetID := luxState.XCTX.UTXOAssetID
|
|
|
|
xWallet := wallet.X()
|
|
exportTx, err := xWallet.IssueExportTx(
|
|
pChainID,
|
|
[]*lux.TransferableOutput{
|
|
{
|
|
Asset: lux.Asset{ID: luxAssetID},
|
|
Out: &secp256k1fx.TransferOutput{
|
|
Amt: *amount,
|
|
OutputOwners: secp256k1fx.OutputOwners{
|
|
Threshold: 1,
|
|
Addrs: []ids.ShortID{pAddr},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
)
|
|
if err != nil {
|
|
log.Fatalf("Failed to issue export tx: %v", err)
|
|
}
|
|
log.Printf("Export TX ID: %s", exportTx.ID())
|
|
|
|
// Wait for export to be accepted
|
|
log.Println("Waiting for export to be accepted...")
|
|
time.Sleep(2 * time.Second)
|
|
|
|
// Step 2: Import on P-Chain
|
|
log.Println("Step 2: Importing on P-Chain...")
|
|
|
|
// Recreate wallet to pick up new UTXOs
|
|
wallet, err = primary.MakeWallet(ctx, &primary.WalletConfig{
|
|
URI: *uri,
|
|
LUXKeychain: kcAdapter,
|
|
EthKeychain: kcAdapter,
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("Failed to recreate wallet: %v", err)
|
|
}
|
|
|
|
pWallet := wallet.P()
|
|
|
|
// Get X-Chain ID for import source (from already-fetched state)
|
|
xChainID := luxState.XCTX.BlockchainID
|
|
|
|
importTx, err := pWallet.IssueImportTx(
|
|
xChainID,
|
|
&secp256k1fx.OutputOwners{
|
|
Threshold: 1,
|
|
Addrs: []ids.ShortID{pAddr},
|
|
},
|
|
)
|
|
if err != nil {
|
|
log.Fatalf("Failed to issue import tx: %v", err)
|
|
}
|
|
log.Printf("Import TX ID: %s", importTx.ID())
|
|
|
|
log.Println("Transfer complete!")
|
|
log.Printf("Transferred %d nLUX from X-Chain to P-Chain", *amount)
|
|
}
|