Skip to content

Instantly share code, notes, and snippets.

@cgcardona
Last active November 21, 2023 23:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cgcardona/df5f099484ee16d31d27503f58843b96 to your computer and use it in GitHub Desktop.
Save cgcardona/df5f099484ee16d31d27503f58843b96 to your computer and use it in GitHub Desktop.
import { Avalanche, BN, Buffer } from "avalanche/dist"
import {
AVMAPI,
KeyChain,
UTXOSet,
UnsignedTx,
Tx,
KeyPair,
SelectCredentialClass
} from "avalanche/dist/apis/avm"
import {
GetBalanceResponse,
GetUTXOsResponse
} from "avalanche/dist/apis/avm/interfaces"
import { Defaults } from "avalanche/dist/utils"
import {
PrivateKeyPrefix,
DefaultLocalGenesisPrivateKey,
DefaultEVMLocalGenesisPrivateKey,
UnixNow
} from "avalanche/dist/utils"
import createHash from "create-hash"
import { Signature, Credential } from "avalanche/dist/common/credentials"
const ip: string = "api.avax-test.network/ext/bc/X"
const port: number = 443
const protocol: string = "https"
const networkID: number = 5
const xBlockchainID: string = Defaults.network[networkID].X.blockchainID
const avaxAssetID = Defaults.network[networkID].X.avaxAssetID as string
const avalanche: Avalanche = new Avalanche(
ip,
port,
protocol,
networkID,
xBlockchainID
)
const xchain: AVMAPI = avalanche.XChain()
const xKeychain: KeyChain = xchain.keyChain()
const privKey: string = `${PrivateKeyPrefix}${DefaultLocalGenesisPrivateKey}`
// this is an example of a single privkey string in hex format
const privKeyStr: string = `${DefaultEVMLocalGenesisPrivateKey}`
xKeychain.importKey(privKey)
const xAddressStrings: string[] = xchain.keyChain().getAddressStrings()
const asOf: BN = UnixNow()
const threshold: number = 1
const locktime: BN = new BN(0)
const memo: Buffer = Buffer.from("AVM utility method buildBaseTx to send AVAX")
const fee: BN = xchain.getDefaultTxFee()
const main = async (): Promise<any> => {
const getBalanceResponse: GetBalanceResponse = await xchain.getBalance(
xAddressStrings[0],
avaxAssetID
)
const balance: BN = new BN(getBalanceResponse.balance)
const avmUTXOResponse: GetUTXOsResponse = await xchain.getUTXOs(
xAddressStrings
)
const utxoSet: UTXOSet = avmUTXOResponse.utxos
const amount: BN = balance.sub(fee)
const unsignedTx: UnsignedTx = await xchain.buildBaseTx(
utxoSet,
amount,
avaxAssetID,
xAddressStrings,
xAddressStrings,
xAddressStrings,
memo,
asOf,
locktime,
threshold
)
// create a keypair which we'll soon over write with importKey
const hrp: string = 'fuji'
const chainID: string = "2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm"
const keypair: KeyPair = new KeyPair(hrp, chainID)
// remove 0x from hex string
const substring: string = privKeyStr.slice(2)
const privKey: Buffer = Buffer.from(substring, "hex")
// import the single hex privkey to create a keypair
keypair.importKey(privKey)
const txbuff = unsignedTx.toBuffer()
const msg: Buffer = Buffer.from(
createHash("sha256").update(txbuff).digest()
)
// this example works only if you have a single output with a single signature. If you have more complex transactions
// such as multiple outputs or multisig then this example will not work and you'll need to
// expand it based on how it works here
// the X-Chain has SECP assets and NFT assets. The SECP asset credential ID is 9
const secpCredentialID: number = 9
const cred: Credential = SelectCredentialClass(secpCredentialID)
const signval: Buffer = keypair.sign(msg)
const sig: Signature = new Signature()
sig.fromBuffer(signval)
const creds: Credential[] = []
cred.addSignature(sig)
creds.push(cred)
const tx: Tx = new Tx(unsignedTx, creds)
const txid: string = await xchain.issueTx(tx)
console.log(`Success! TXID: ${txid}`)
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment