Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions modules/sdk-coin-avaxp/src/lib/atomicTransactionBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from 'avalanche/dist/apis/platformvm';
import { Credential } from 'avalanche/dist/common';
import { BuildTransactionError } from '@bitgo/sdk-core';
import { SECP256K1_Transfer_Output } from './iface';
import { SECP256K1_STAKEABLE_LOCK_OUT, SECP256K1_Transfer_Output } from './iface';

/**
* Cross-chain transactions (export and import) are atomic operations.
Expand Down Expand Up @@ -104,7 +104,10 @@ export abstract class AtomicTransactionBuilder extends DeprecatedTransactionBuil
});

this.transaction._utxos.forEach((utxo, i) => {
if (utxo.outputID === SECP256K1_Transfer_Output) {
if (
utxo.outputID === SECP256K1_Transfer_Output ||
(utxo.outputID === SECP256K1_STAKEABLE_LOCK_OUT && utxo.locktime === '0')
) {
const txidBuf = utils.cb58Decode(utxo.txid);
const amt: BN = new BN(utxo.amount);
const outputidx = utils.outputidxNumberToBuffer(utxo.outputidx);
Expand Down
7 changes: 5 additions & 2 deletions modules/sdk-coin-avaxp/src/lib/delegatorTxBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
UnsignedTx,
} from 'avalanche/dist/apis/platformvm';
import { BinTools, BN } from 'avalanche';
import { SECP256K1_Transfer_Output, DeprecatedTx, DeprecatedBaseTx } from './iface';
import { SECP256K1_Transfer_Output, DeprecatedTx, DeprecatedBaseTx, SECP256K1_STAKEABLE_LOCK_OUT } from './iface';
import utils from './utils';
import { Credential } from 'avalanche/dist/common';
import { deprecatedRecoverUtxos } from './utxoEngine';
Expand Down Expand Up @@ -309,7 +309,10 @@ export class DelegatorTxBuilder extends DeprecatedTransactionBuilder {
const buildOutputs = this.transaction._utxos[0].addresses.length !== 0;

this.transaction._utxos.forEach((utxo, i) => {
if (utxo.outputID === SECP256K1_Transfer_Output) {
if (
utxo.outputID === SECP256K1_Transfer_Output ||
(utxo.outputID === SECP256K1_STAKEABLE_LOCK_OUT && utxo.locktime === '0')
) {
const txidBuf = utils.cb58Decode(utxo.txid);
const amt: BN = new BN(utxo.amount);
const outputidx = utils.outputidxNumberToBuffer(utxo.outputidx);
Expand Down
8 changes: 7 additions & 1 deletion modules/sdk-coin-avaxp/src/lib/iface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface TxData {
*/
export type DecodedUtxoObj = {
outputID: number;
locktime?: string;
amount: string;
txid: string;
outputidx: string;
Expand All @@ -61,9 +62,14 @@ export type DecodedUtxoObj = {
/**
* TypeId value for SECP256K1 Transfer Output
*
* {@link https://docs.avax.network/specs/platform-transaction-serialization#secp256k1-transfer-output-example }
* {@link https://build.avax.network/docs/api-reference/p-chain/txn-format#secp256k1-transfer-output }
*/
export const SECP256K1_Transfer_Output = 7;
/**
* TypeId value for Stakeable Lock Output
* {@link https://build.avax.network/docs/api-reference/p-chain/txn-format#stakeablelockout }
*/
export const SECP256K1_STAKEABLE_LOCK_OUT = 22;

export const ADDRESS_SEPARATOR = '~';
export const INPUT_SEPARATOR = ':';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
import { BaseCoin as CoinConfig } from '@bitgo/statics';
import { Buffer as BufferAvax } from 'avalanche';
import BigNumber from 'bignumber.js';
import { DecodedUtxoObj, SECP256K1_Transfer_Output, Tx } from './iface';
import { DecodedUtxoObj, SECP256K1_STAKEABLE_LOCK_OUT, SECP256K1_Transfer_Output, Tx } from './iface';
import { KeyPair } from './keyPair';
import { Transaction } from './transaction';
import { TransactionBuilder } from './transactionBuilder';
Expand Down Expand Up @@ -291,9 +291,6 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
this.transaction._stakeAmount = permissionlessValidatorTx.stake[0].output.amount();
this.stakeAmount(this.transaction._stakeAmount);
this.transaction._utxos = recoverUtxos(permissionlessValidatorTx.getInputs());
// TODO(CR-1073): remove log
console.log('utxos: ', this.transaction._utxos);
console.log('fromAddresses: ', this.transaction.fromAddresses);
return this;
}

Expand Down Expand Up @@ -338,8 +335,6 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
const bitgoAddresses = this.transaction._fromAddresses.map((b) =>
avaxUtils.format(this.transaction._network.alias, this.transaction._network.hrp, b)
);
// TODO(CR-1073): remove log
console.log(`bitgoAddress: ${bitgoAddresses}`);

// if we are in OVC, none of the utxos will have addresses since they come from
// deserialized inputs (which don't have addresses), not the IMS
Expand Down Expand Up @@ -371,12 +366,12 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
utxo.addresses.forEach((a) => {
bitgoIndexToOnChainIndex.set(bitgoAddresses.indexOf(a), utxo.addresses.indexOf(a));
});
// TODO(CR-1073): remove log
console.log(`utxo.addresses: ${utxo.addresses}`);
console.log(`bitgoIndexToOnChainIndex: ${Array.from(bitgoIndexToOnChainIndex)}`);
// in OVC, output.addressesIndex is defined correctly from the previous iteration

if (utxo.outputID === SECP256K1_Transfer_Output) {
if (
utxo.outputID === SECP256K1_Transfer_Output ||
(utxo.outputID === SECP256K1_STAKEABLE_LOCK_OUT && utxo.locktime === '0')
) {
const utxoAmount = BigInt(utxo.amount);
// either user (0) or recovery (2)
// On regular mode: [user, bitgo] (i.e. [0, 1])
Expand All @@ -400,8 +395,6 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
new BigIntPr(utxoAmount),
new Input([...addressesIndex].sort().map((num) => new Int(num)))
);
// TODO(CR-1073): remove log
console.log(`using addressesIndex sorted: ${[...addressesIndex].sort()}`);

const input = new avaxSerial.TransferableInput(utxoId, assetId, transferInputs);
utxos.push(new Utxo(utxoId, assetId, transferInputs));
Expand All @@ -413,12 +406,7 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
// For the user/backup signature we store the address that matches the key
// if bitgo address comes before < user/backup address

// TODO(CR-1073): remove log
console.log(`bitgo index on chain: ${utxo.addressesIndex[bitgoIndex]}`);
console.log(`user Or Backup Index: ${utxo.addressesIndex[userOrBackupIndex]}`);
if (utxo.addressesIndex[bitgoIndex] < utxo.addressesIndex[userOrBackupIndex]) {
// TODO(CR-1073): remove log
console.log(`user or backup credentials after bitgo`);
credentials.push(
new Credential([
utils.createNewSig(BufferAvax.from('').toString('hex')),
Expand All @@ -428,8 +416,6 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
])
);
} else {
// TODO(CR-1073): remove log
console.log(`user or backup credentials before bitgo`);
credentials.push(
new Credential([
utils.createNewSig(
Expand All @@ -440,7 +426,6 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
);
}
} else {
// TODO(CR-1073): verify this else case for OVC
credentials.push(
new Credential(
addressesIndex.map((i) =>
Expand All @@ -449,9 +434,6 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
)
);
}
} else {
// TODO(CR-1073): remove log
console.log(`reusing credentials from transaction`);
}
}
});
Expand Down Expand Up @@ -542,9 +524,8 @@ export class PermissionlessValidatorTxBuilder extends TransactionBuilder {
.map((a) => Address.fromBytes(a)[0])
);

// TODO(CR-1073): check this value
// Shares 10,000 times percentage of reward taken from delegators
// https://docs.avax.network/reference/avalanchego/p-chain/txn-format#unsigned-add-validator-tx
// Shares 10,000 times percentage of reward taken from delegators
// https://docs.avax.network/reference/avalanchego/p-chain/txn-format#unsigned-add-validator-tx
const shares = new Int(1e4 * 2);

const addressMaps = [...this.transaction._fromAddresses]
Expand Down
9 changes: 0 additions & 9 deletions modules/sdk-coin-avaxp/src/lib/transactionBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,21 +131,12 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder {
return this;
}

// TODO(CR-1073):
// Implement:
// buildImplementation
// signImplementation
// get transaction
// set transaction
// validateRawTransaction

/** @inheritdoc */
protected fromImplementation(rawTransaction: string): Transaction {
const [tx] = pvmSerial.AddPermissionlessValidatorTx.fromBytes(
Buffer.from(rawTransaction, 'hex'),
avmSerial.getAVMManager().getDefaultCodec()
);
// TODO(CR-1073): check if initBuilder can only use UnsignedTx and pvmSerial.BaseTx is not required
this.initBuilder(tx);
return this._transaction;
}
Expand Down
9 changes: 7 additions & 2 deletions modules/sdk-coin-avaxp/src/lib/utxoEngine.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DecodedUtxoObj, SECP256K1_Transfer_Output } from './iface';
import { DecodedUtxoObj, SECP256K1_STAKEABLE_LOCK_OUT, SECP256K1_Transfer_Output } from './iface';
import { BN, Buffer as BufferAvax } from 'avalanche';
import { Signature } from 'avalanche/dist/common';
import utils from './utils';
Expand Down Expand Up @@ -98,7 +98,12 @@ export function utxoToInput(
let currentTotal: BN = new BN(0);

const inputs = utxos
.filter((utxo) => utxo && utxo.outputID === SECP256K1_Transfer_Output)
.filter(
(utxo) =>
utxo &&
(utxo.outputID === SECP256K1_Transfer_Output ||
(utxo.outputID === SECP256K1_STAKEABLE_LOCK_OUT && utxo.locktime === '0'))
)
.map((utxo) => {
// validate the utxos
const utxoAddresses: BufferAvax[] = utxo.addresses.map((a) => utils.parseAddress(a));
Expand Down
2 changes: 1 addition & 1 deletion modules/sdk-coin-avaxp/test/resources/avaxp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ export const BUILD_AND_SIGN_ADD_PERMISSIONLESS_VALIDATOR_SAMPLE = {
'0xa94d6182edbd953516b262f17565a65d98f5741549cd70d2423abff750bb4b8d982d482376b189142ff8aa4705615fee14be6174610860e9c003aa4aeaa613b1732abf3cd0c9c42fa5856345644068c0d1f9fa1d9af32e20b14fca02983260bc',
utxos: [
{
outputID: 7,
outputID: 22,
amount: '98000000',
txid: 's92SjoZQemgG97HocX9GgyFy6ZKmapgcgqQ3y5J2uwP3qWBUy',
threshold: 2,
Expand Down