Skip to content

Commit

Permalink
feat: add p-chain etna examples
Browse files Browse the repository at this point in the history
  • Loading branch information
erictaylor committed Sep 13, 2024
1 parent afa2f2d commit 36dd950
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 2 deletions.
42 changes: 42 additions & 0 deletions examples/p-chain/etna/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { TransferableOutput, addTxSignatures, pvm, utils } from '../../../src';
import { getEnvVars } from '../../utils/getEnvVars';
import { getEtnaContextFromURI } from './utils/etna-context';

/**
* The amount of AVAX to send to self.
*/
const SEND_AVAX_AMOUNT: number = 0.001;

const main = async () => {
const { AVAX_PUBLIC_URL, P_CHAIN_ADDRESS, PRIVATE_KEY } = getEnvVars();

const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);

const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);

const { utxos } = await pvmApi.getUTXOs({ addresses: [P_CHAIN_ADDRESS] });

const tx = pvm.e.newBaseTx(
{
fromAddressesBytes: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
outputs: [
TransferableOutput.fromNative(
context.avaxAssetID,
BigInt(SEND_AVAX_AMOUNT * 1e9),
[utils.bech32ToBytes(P_CHAIN_ADDRESS)],
),
],
utxos,
},
context,
);

await addTxSignatures({
unsignedTx: tx,
privateKeys: [utils.hexToBuffer(PRIVATE_KEY)],
});

return pvmApi.issueSignedTx(tx.getSignedTx());
};

main().then(console.log);
49 changes: 49 additions & 0 deletions examples/p-chain/etna/delegate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { addTxSignatures, networkIDs, pvm, utils } from '../../../src';
import { getEnvVars } from '../../utils/getEnvVars';
import { getEtnaContextFromURI } from './utils/etna-context';

const AMOUNT_TO_DELEGATE_AVAX: number = 1;
const DAYS_TO_DELEGATE: number = 21;

const main = async () => {
const { AVAX_PUBLIC_URL, P_CHAIN_ADDRESS, PRIVATE_KEY } = getEnvVars();

const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);

const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);

const { utxos } = await pvmApi.getUTXOs({ addresses: [P_CHAIN_ADDRESS] });

const startTime = await pvmApi.getTimestamp();
const startDate = new Date(startTime.timestamp);
const start: bigint = BigInt(startDate.getTime() / 1_000);

const endTime = new Date(startTime.timestamp);
endTime.setDate(endTime.getDate() + DAYS_TO_DELEGATE);
const end: bigint = BigInt(endTime.getTime() / 1_000);

const nodeId = 'NodeID-HKLp5269LH8DcrLvHPc2PHjGczBQD3td4';

const tx = pvm.e.newAddPermissionlessDelegatorTx(
{
end,
fromAddressesBytes: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
nodeId,
rewardAddresses: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
start,
subnetId: networkIDs.PrimaryNetworkID.toString(),
utxos,
weight: BigInt(AMOUNT_TO_DELEGATE_AVAX * 1e9),
},
context,
);

await addTxSignatures({
unsignedTx: tx,
privateKeys: [utils.hexToBuffer(PRIVATE_KEY)],
});

return pvmApi.issueSignedTx(tx.getSignedTx());
};

main().then(console.log);
43 changes: 43 additions & 0 deletions examples/p-chain/etna/export.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { TransferableOutput, addTxSignatures, pvm, utils } from '../../../src';
import { getEnvVars } from '../../utils/getEnvVars';
import { getEtnaContextFromURI } from './utils/etna-context';

const AMOUNT_TO_EXPORT_AVAX: number = 0.001;

const main = async () => {
const { AVAX_PUBLIC_URL, P_CHAIN_ADDRESS, PRIVATE_KEY, X_CHAIN_ADDRESS } =
getEnvVars();

const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);

const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);

const { utxos } = await pvmApi.getUTXOs({
addresses: [P_CHAIN_ADDRESS],
});

const exportTx = pvm.e.newExportTx(
{
destinationChainId: context.xBlockchainID,
fromAddressesBytes: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
outputs: [
TransferableOutput.fromNative(
context.avaxAssetID,
BigInt(AMOUNT_TO_EXPORT_AVAX * 1e9),
[utils.bech32ToBytes(X_CHAIN_ADDRESS)],
),
],
utxos,
},
context,
);

await addTxSignatures({
unsignedTx: exportTx,
privateKeys: [utils.hexToBuffer(PRIVATE_KEY)],
});

return pvmApi.issueSignedTx(exportTx.getSignedTx());
};

main().then(console.log);
36 changes: 36 additions & 0 deletions examples/p-chain/etna/import.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { addTxSignatures, pvm, utils } from '../../../src';
import { getEnvVars } from '../../utils/getEnvVars';
import { getEtnaContextFromURI } from './utils/etna-context';

const main = async () => {
const { AVAX_PUBLIC_URL, P_CHAIN_ADDRESS, PRIVATE_KEY, X_CHAIN_ADDRESS } =
getEnvVars();

const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);

const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);

const { utxos } = await pvmApi.getUTXOs({
sourceChain: 'X',
addresses: [P_CHAIN_ADDRESS],
});

const importTx = pvm.e.newImportTx(
{
fromAddressesBytes: [utils.bech32ToBytes(X_CHAIN_ADDRESS)],
sourceChainId: context.xBlockchainID,
toAddresses: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
utxos,
},
context,
);

await addTxSignatures({
unsignedTx: importTx,
privateKeys: [utils.hexToBuffer(PRIVATE_KEY)],
});

return pvmApi.issueSignedTx(importTx.getSignedTx());
};

main().then(console.log);
16 changes: 16 additions & 0 deletions examples/p-chain/etna/utils/etna-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Context } from '../../../../src';

/**
* Gets the context from URI and then modifies the context
* to be used for testing example Etna transactions until Etna is enabled.
*/
export const getEtnaContextFromURI = async (
uri: string,
): Promise<Context.Context> => {
const context = await Context.getContextFromURI(uri);

return {
...context,
gasPrice: 10_000n,
};
};
61 changes: 61 additions & 0 deletions examples/p-chain/etna/validate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { addTxSignatures, networkIDs, pvm, utils } from '../../../src';
import { getEnvVars } from '../../utils/getEnvVars';
import { getEtnaContextFromURI } from './utils/etna-context';

const AMOUNT_TO_VALIDATE_AVAX: number = 1;
const DAYS_TO_VALIDATE: number = 21;

const main = async () => {
const { AVAX_PUBLIC_URL, P_CHAIN_ADDRESS, PRIVATE_KEY } = getEnvVars();

const pvmApi = new pvm.PVMApi(AVAX_PUBLIC_URL);

const context = await getEtnaContextFromURI(AVAX_PUBLIC_URL);

const { utxos } = await pvmApi.getUTXOs({ addresses: [P_CHAIN_ADDRESS] });

const startTime = await pvmApi.getTimestamp();
const startDate = new Date(startTime.timestamp);
const start: bigint = BigInt(startDate.getTime() / 1_000);

const endTime = new Date(startTime.timestamp);
endTime.setDate(endTime.getDate() + DAYS_TO_VALIDATE);
const end: bigint = BigInt(endTime.getTime() / 1_000);

const nodeId = 'NodeID-HKLp5269LH8DcrLvNDoJquQs2w1LwLCga';

const publicKey = utils.hexToBuffer(
'0x8f95423f7142d00a48e1014a3de8d28907d420dc33b3052a6dee03a3f2941a393c2351e354704ca66a3fc29870282e15',
);

const signature = utils.hexToBuffer(
'0x86a3ab4c45cfe31cae34c1d06f212434ac71b1be6cfe046c80c162e057614a94a5bc9f1ded1a7029deb0ba4ca7c9b71411e293438691be79c2dbf19d1ca7c3eadb9c756246fc5de5b7b89511c7d7302ae051d9e03d7991138299b5ed6a570a98',
);

const tx = pvm.e.newAddPermissionlessValidatorTx(
{
end,
delegatorRewardsOwner: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
fromAddressesBytes: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
nodeId,
publicKey,
rewardAddresses: [utils.bech32ToBytes(P_CHAIN_ADDRESS)],
shares: 20 * 1e4,
signature,
start,
subnetId: networkIDs.PrimaryNetworkID.toString(),
utxos,
weight: BigInt(AMOUNT_TO_VALIDATE_AVAX * 1e9),
},
context,
);

await addTxSignatures({
unsignedTx: tx,
privateKeys: [utils.hexToBuffer(PRIVATE_KEY)],
});

return pvmApi.issueSignedTx(tx.getSignedTx());
};

main().then(console.log);
17 changes: 17 additions & 0 deletions examples/utils/getEnvVars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const AVAX_PUBLIC_URL = process.env['AVAX_PUBLIC_URL'];
const P_CHAIN_ADDRESS = process.env['P_CHAIN_ADDRESS'];
const PRIVATE_KEY = process.env['PRIVATE_KEY'];
const X_CHAIN_ADDRESS = process.env['X_CHAIN_ADDRESS'];

export const getEnvVars = () => {
if (!(AVAX_PUBLIC_URL && P_CHAIN_ADDRESS && PRIVATE_KEY && X_CHAIN_ADDRESS)) {
throw new Error('Missing environment variable(s).');
}

return {
AVAX_PUBLIC_URL,
P_CHAIN_ADDRESS,
PRIVATE_KEY,
X_CHAIN_ADDRESS,
};
};
4 changes: 2 additions & 2 deletions src/vms/context/context.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getHRP } from '../../constants/networkIDs';
import { Info } from '../../info/info';
import { AVMApi } from '../avm/api';
import { createEmptyDimensions } from '../common/fees/dimensions';
import { createDimensions } from '../common/fees/dimensions';
import type { Context } from './model';

/*
Expand Down Expand Up @@ -52,6 +52,6 @@ export const getContextFromURI = async (

// TODO: Populate these values once they are exposed by the API
gasPrice: 0n,
complexityWeights: createEmptyDimensions(),
complexityWeights: createDimensions(1, 1, 1, 1),
});
};

0 comments on commit 36dd950

Please sign in to comment.