Skip to content

Commit

Permalink
[TX] Add DepositTx
Browse files Browse the repository at this point in the history
  • Loading branch information
peak3d committed Jan 9, 2023
1 parent cbce3ad commit 956fba2
Show file tree
Hide file tree
Showing 6 changed files with 424 additions and 3 deletions.
71 changes: 71 additions & 0 deletions examples/platformvm/buildDepositTx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Avalanche, Buffer } from "@c4tplatform/caminojs/dist"
import {
PlatformVMAPI,
KeyChain,
UnsignedTx,
Tx
} from "@c4tplatform/caminojs/dist/apis/platformvm"
import { OutputOwners } from "@c4tplatform/caminojs/dist/common/output"
import {
PrivateKeyPrefix,
DefaultLocalGenesisPrivateKey
} from "@c4tplatform/caminojs/dist/utils"
import { ExamplesConfig } from "../common/examplesConfig"

const config: ExamplesConfig = require("../common/examplesConfig.json")
const avalanche: Avalanche = new Avalanche(
config.host,
config.port,
config.protocol,
config.networkID
)

/**
* @ignore
*/
let privKey: string = `${PrivateKeyPrefix}${DefaultLocalGenesisPrivateKey}`

let pchain: PlatformVMAPI
let pKeychain: KeyChain
let pAddressStrings: string[]

const InitAvalanche = async () => {
await avalanche.fetchNetworkSettings()
pchain = avalanche.PChain()
pKeychain = pchain.keyChain()
// P-local18jma8ppw3nhx5r4ap8clazz0dps7rv5u9xde7p
pKeychain.importKey(privKey)

pAddressStrings = pchain.keyChain().getAddressStrings()
}

const main = async (): Promise<any> => {
await InitAvalanche()

const depositOfferID = "wVVZinZkN9x6e9dh3DNNfrmdXaHPPwKWt3Zerx2vD8Ccuo6E7"
const depositDuration = 110376000
const memo: Buffer = Buffer.from(
"Utility function to create a DepositTx transaction"
)
const owners = new OutputOwners(
pchain.keyChain().getAddresses(),
undefined,
1
)

const unsignedTx: UnsignedTx = await pchain.buildDepositTx(
undefined,
pAddressStrings,
pAddressStrings,
depositOfferID,
depositDuration,
owners,
memo
)

const tx: Tx = unsignedTx.sign(pKeychain)
const txid: string = await pchain.issueTx(tx)
console.log(`Success! TXID: ${txid}`)
}

main()
73 changes: 72 additions & 1 deletion src/apis/platformvm/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import { Buffer } from "buffer/"
import BN from "bn.js"
import AvalancheCore from "../../camino"
import { JRPCAPI } from "../../common/jrpcapi"
import { RequestResponseData } from "../../common/apibase"
import { JRPCAPI } from "../../common/jrpcapi"
import { OutputOwners } from "../../common/output"

import {
ErrorResponseObject,
ProtocolError,
Expand Down Expand Up @@ -2010,6 +2012,75 @@ export class PlatformVMAPI extends JRPCAPI {
return builtUnsignedTx
}

/**
* Build an unsigned [[DepositTx]].
*
* @param utxoset A set of UTXOs that the transaction is built on
* @param fromAddresses The addresses being used to send the funds from the UTXOs {@link https://github.com/feross/buffer|Buffer}
* @param changeAddresses The addresses that can spend the change remaining from the spent UTXOs.
* @param depositOfferID ID of the deposit offer.
* @param depositDuration Duration of the deposit
* @param rewardsOwner Optional The owners of the reward. If omitted, all inputs must have the same owner
* @param memo Optional contains arbitrary bytes, up to 256 bytes
* @param asOf Optional. The timestamp to verify the transaction against as a {@link https://github.com/indutny/bn.js/|BN}
* @param changeThreshold Optional. The number of signatures required to spend the funds in the resultant change UTXO
*
* @returns An unsigned transaction created from the passed in parameters.
*/
buildDepositTx = async (
utxoset: UTXOSet,
fromAddresses: string[],
changeAddresses: string[] = undefined,
depositOfferID: string | Buffer,
depositDuration: number | Buffer,
rewardsOwner: OutputOwners = undefined,
memo: PayloadBase | Buffer = undefined,
asOf: BN = ZeroBN,
changeThreshold: number = 1
): Promise<UnsignedTx> => {
const from: Buffer[] = this._cleanAddressArray(
fromAddresses,
"buildRegisterNodeTx"
).map((a: string): Buffer => bintools.stringToAddress(a))
const change: Buffer[] = this._cleanAddressArray(
changeAddresses,
"buildRegisterNodeTx"
).map((a: string): Buffer => bintools.stringToAddress(a))

if (memo instanceof PayloadBase) {
memo = memo.getPayload()
}

const avaxAssetID: Buffer = await this.getAVAXAssetID()
const networkID: number = this.core.getNetworkID()
const blockchainID: Buffer = bintools.cb58Decode(this.blockchainID)
const fee: BN = this.getTxFee()

const builtUnsignedTx: UnsignedTx = await this._getBuilder(
utxoset
).buildDepositTx(
networkID,
blockchainID,
from,
change,
depositOfferID,
depositDuration,
rewardsOwner,
fee,
avaxAssetID,
memo,
asOf,
changeThreshold
)

if (!(await this.checkGooseEgg(builtUnsignedTx, this.getCreationTxFee()))) {
/* istanbul ignore next */
throw new GooseEggCheckError("Failed Goose Egg Check")
}

return builtUnsignedTx
}

/**
* @ignore
*/
Expand Down
82 changes: 82 additions & 0 deletions src/apis/platformvm/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import BN from "bn.js"

import { Buffer } from "buffer/"
import { OutputOwners } from "../../common/output"
import { DefaultNetworkID, UnixNow } from "../../utils"
import {
AddressError,
Expand Down Expand Up @@ -38,6 +39,7 @@ import {
UTXO
} from "."
import { GenesisData } from "../avm"
import { DepositTx } from "./depositTx"

export type LockMode = "Unlocked" | "Bond" | "Deposit" | "Stake"

Expand Down Expand Up @@ -1117,6 +1119,86 @@ export class Builder {
return new UnsignedTx(registerNodeTx)
}

/**
* Build an unsigned [[DepositTx]].
*
* @param networkID Networkid, [[DefaultNetworkID]]
* @param blockchainID Blockchainid, default undefined
* @param fromAddresses The addresses being used to send the funds from the UTXOs {@link https://github.com/feross/buffer|Buffer}
* @param changeAddresses The addresses that can spend the change remaining from the spent UTXOs.
* @param depositOfferID ID of the deposit offer.
* @param depositDuration Duration of the deposit
* @param rewardsOwner Optional The owners of the reward. If omitted, all inputs must have the same owner
* @param fee Optional. The amount of fees to burn in its smallest denomination, represented as {@link https://github.com/indutny/bn.js/|BN}
* @param feeAssetID Optional. The assetID of the fees being burned
* @param memo Optional contains arbitrary bytes, up to 256 bytes
* @param asOf Optional. The timestamp to verify the transaction against as a {@link https://github.com/indutny/bn.js/|BN}
* @param changeThreshold Optional. The number of signatures required to spend the funds in the resultant change UTXO
*
* @returns An unsigned DepositTx created from the passed in parameters.
*/
buildDepositTx = async (
networkID: number = DefaultNetworkID,
blockchainID: Buffer,
fromAddresses: Buffer[],
changeAddresses: Buffer[],
depositOfferID: string | Buffer,
depositDuration: number | Buffer,
rewardsOwner: OutputOwners,
fee: BN = zero,
feeAssetID: Buffer = undefined,
memo: Buffer = undefined,
asOf: BN = zero,
changeThreshold: number = 1
): Promise<UnsignedTx> => {
let ins: TransferableInput[] = []
let outs: TransferableOutput[] = []

if (this._feeCheck(fee, feeAssetID)) {
const aad: AssetAmountDestination = new AssetAmountDestination(
[],
0,
fromAddresses,
changeAddresses,
changeThreshold
)

aad.addAssetAmount(feeAssetID, zero, fee)

const minSpendableErr: Error = await this.spender.getMinimumSpendable(
aad,
asOf,
zero,
"Unlocked"
)
if (typeof minSpendableErr === "undefined") {
ins = aad.getInputs()
outs = aad.getAllOutputs()
} else {
throw minSpendableErr
}
}

const secpOwners = new SECPOwnerOutput(
rewardsOwner.getAddresses(),
rewardsOwner?.getLocktime(),
rewardsOwner.getThreshold()
)

const depositTx: DepositTx = new DepositTx(
networkID,
blockchainID,
outs,
ins,
memo,
depositOfferID,
depositDuration,
new ParseableOutput(secpOwners)
)

return new UnsignedTx(depositTx)
}

_feeCheck(fee: BN, feeAssetID: Buffer): boolean {
return (
typeof fee !== "undefined" &&
Expand Down
Loading

0 comments on commit 956fba2

Please sign in to comment.