diff --git a/packages/demo/components/pages/apis/transaction/builder/delegateStakeCertificate.tsx b/packages/demo/components/pages/apis/transaction/builder/delegateStakeCertificate.tsx
new file mode 100644
index 000000000..a56e92b0d
--- /dev/null
+++ b/packages/demo/components/pages/apis/transaction/builder/delegateStakeCertificate.tsx
@@ -0,0 +1,28 @@
+import Section from '../../../../common/section';
+import Codeblock from '../../../../ui/codeblock';
+
+export default function DeregisterCertificate() {
+ return (
+
+ );
+}
+
+function Content() {
+ let code = `mesh
+ .delegateStakeCertificate(stakeKeyHash: string, poolId: string)`;
+
+ return (
+ <>
+
+ Use .delegateStakeCertificate()
to delegate a stake to a
+ pool:
+
+
+
+ >
+ );
+}
diff --git a/packages/demo/components/pages/apis/transaction/builder/deregisterCertificate.tsx b/packages/demo/components/pages/apis/transaction/builder/deregisterCertificate.tsx
new file mode 100644
index 000000000..070781248
--- /dev/null
+++ b/packages/demo/components/pages/apis/transaction/builder/deregisterCertificate.tsx
@@ -0,0 +1,28 @@
+import Section from '../../../../common/section';
+import Codeblock from '../../../../ui/codeblock';
+
+export default function DeregisterCertificate() {
+ return (
+
+ );
+}
+
+function Content() {
+ let code = `mesh
+ .deregisterStakeCertificate(stakeKeyHash: string)`;
+
+ return (
+ <>
+
+ Use .deregisterStakeCertificate()
to deregister a stake
+ certificate:
+
+
+
+ >
+ );
+}
diff --git a/packages/demo/components/pages/apis/transaction/builder/mintNative.tsx b/packages/demo/components/pages/apis/transaction/builder/mintNative.tsx
index 5aeb2e521..7abee46eb 100644
--- a/packages/demo/components/pages/apis/transaction/builder/mintNative.tsx
+++ b/packages/demo/components/pages/apis/transaction/builder/mintNative.tsx
@@ -13,15 +13,18 @@ export default function Mint() {
function Content() {
let code = `mesh
- .mint(quantity: number, policy: string, name: string)
+ .mint(quantity: string, policy: string, name: string)
.mintingScript(scriptCbor: string)
`;
return (
<>
- When minting tokens using a 'native script' as input, there are 2 steps:
+
+ When minting tokens using a 'native script' as input, there are 2 steps:
+
- 1. Providing the minting value (quantity, policy and name) using .mint()
+ 1. Providing the minting value (quantity, policy and name) using{' '}
+ .mint()
2. Providing the script source using
diff --git a/packages/demo/components/pages/apis/transaction/builder/mintPlutus.tsx b/packages/demo/components/pages/apis/transaction/builder/mintPlutus.tsx
index 0b475d51d..2c52d180d 100644
--- a/packages/demo/components/pages/apis/transaction/builder/mintPlutus.tsx
+++ b/packages/demo/components/pages/apis/transaction/builder/mintPlutus.tsx
@@ -14,7 +14,7 @@ export default function Mint() {
function Content() {
let code = `mesh
.mintPlutusScriptV2()
- .mint(quantity: number, policy: string, name: string)
+ .mint(quantity: string, policy: string, name: string)
.mintTxInReference(txHash: string, txIndex: number) // or .mintingScript(scriptCbor: string)
.mintRedeemerValue(redeemer: Data | object | string, exUnits?: Budget, type?: "Mesh" | "CBOR" | "JSON")
`;
diff --git a/packages/demo/components/pages/apis/transaction/builder/registerCertificate.tsx b/packages/demo/components/pages/apis/transaction/builder/registerCertificate.tsx
new file mode 100644
index 000000000..a94b155b7
--- /dev/null
+++ b/packages/demo/components/pages/apis/transaction/builder/registerCertificate.tsx
@@ -0,0 +1,28 @@
+import Section from '../../../../common/section';
+import Codeblock from '../../../../ui/codeblock';
+
+export default function RegisterCertificate() {
+ return (
+
+ );
+}
+
+function Content() {
+ let code = `mesh
+ .registerStakeCertificate(stakeKeyHash: string)`;
+
+ return (
+ <>
+
+ Use .registerStakeCertificate()
to register a stake
+ certificate:
+
+
+
+ >
+ );
+}
diff --git a/packages/demo/components/pages/apis/transaction/builder/registerPoolCertificate.tsx b/packages/demo/components/pages/apis/transaction/builder/registerPoolCertificate.tsx
new file mode 100644
index 000000000..460b3bcf9
--- /dev/null
+++ b/packages/demo/components/pages/apis/transaction/builder/registerPoolCertificate.tsx
@@ -0,0 +1,28 @@
+import Section from '../../../../common/section';
+import Codeblock from '../../../../ui/codeblock';
+
+export default function RegisterPoolCertificate() {
+ return (
+
+ );
+}
+
+function Content() {
+ let code = `mesh
+ .registerPoolCertificate(poolParams: PoolParams)`;
+
+ return (
+ <>
+
+ Use .registerPoolCertificate()
to register a pool
+ certificate:
+
+
+
+ >
+ );
+}
diff --git a/packages/demo/components/pages/apis/transaction/builder/retirePoolCertificate.tsx b/packages/demo/components/pages/apis/transaction/builder/retirePoolCertificate.tsx
new file mode 100644
index 000000000..c52ba4919
--- /dev/null
+++ b/packages/demo/components/pages/apis/transaction/builder/retirePoolCertificate.tsx
@@ -0,0 +1,27 @@
+import Section from '../../../../common/section';
+import Codeblock from '../../../../ui/codeblock';
+
+export default function RetirePoolCertificate() {
+ return (
+
+ );
+}
+
+function Content() {
+ let code = `mesh
+ .retirePoolCertificate(poolId: string, epoch: number)`;
+
+ return (
+ <>
+
+ Use .retirePoolCertificate()
to retire a pool certificate:
+
+
+
+ >
+ );
+}
diff --git a/packages/demo/components/pages/apis/transaction/builder/schemas.tsx b/packages/demo/components/pages/apis/transaction/builder/schemas.tsx
index 2d56abc9f..7486ddcaa 100644
--- a/packages/demo/components/pages/apis/transaction/builder/schemas.tsx
+++ b/packages/demo/components/pages/apis/transaction/builder/schemas.tsx
@@ -6,22 +6,23 @@ export default function Schemas() {
}
function Content() {
- let codeMeshTxBuilderBody = ``;
- codeMeshTxBuilderBody += `MeshTxBuilderBody = {\n`;
- codeMeshTxBuilderBody += ` inputs: TxIn[]\n`;
- codeMeshTxBuilderBody += ` outputs: Output[];\n`;
- codeMeshTxBuilderBody += ` collaterals: PubKeyTxIn[];\n`;
- codeMeshTxBuilderBody += ` requiredSignatures: string[];\n`;
- codeMeshTxBuilderBody += ` referenceInputs: RefTxIn[];\n`;
- codeMeshTxBuilderBody += ` mints: MintItem[];\n`;
- codeMeshTxBuilderBody += ` changeAddress: string;\n`;
- codeMeshTxBuilderBody += ` metadata: Metadata[];\n`;
- codeMeshTxBuilderBody += ` validityRange: ValidityRange;\n`;
- codeMeshTxBuilderBody += ` signingKey: string[];\n`;
- codeMeshTxBuilderBody += `}\n`;
-
- let codeInput = ``;
- codeInput += `TxIn = PubKeyTxIn | ScriptTxIn;\n`;
+ let codeMeshTxBuilderBody = `MeshTxBuilderBody = {
+ inputs: TxIn[];
+ outputs: Output[];
+ extraInputs: UTxO[];
+ selectionThreshold: number;
+ collaterals: PubKeyTxIn[];
+ requiredSignatures: string[];
+ referenceInputs: RefTxIn[];
+ mints: MintItem[];
+ changeAddress: string;
+ metadata: Metadata[];
+ validityRange: ValidityRange;
+ certificates: Certificate[];
+ signingKey: string[];
+}`;
+
+ let codeInput = `TxIn = PubKeyTxIn | ScriptTxIn;`;
let codePubKeyTxIn = `PubKeyTxIn = {
type: 'PubKey';
@@ -97,7 +98,7 @@ function Content() {
type: 'Plutus' | 'Native';
policyId: string;
assetName: string;
- amount: number;
+ amount: string;
redeemer?: Redeemer;
scriptSource?:
| {
diff --git a/packages/demo/components/pages/apis/transaction/builderExample/complexTransaction.tsx b/packages/demo/components/pages/apis/transaction/builderExample/complexTransaction.tsx
index 619e30086..0bbb92d8a 100644
--- a/packages/demo/components/pages/apis/transaction/builderExample/complexTransaction.tsx
+++ b/packages/demo/components/pages/apis/transaction/builderExample/complexTransaction.tsx
@@ -20,7 +20,7 @@ function Content() {
.txInRedeemerValue(mConStr0([]))
.txInScript(getScriptCbor("Spending"))
.mintPlutusScriptV2()
- .mint(1, policyId, tokenName)
+ .mint("1", policyId, tokenName)
.mintingScript(mintingScript)
.mintRedeemerValue(mConStr0([]))
.txOut(this.constants.walletAddress, [{ unit: policyId + tokenName, quantity: "1" }])
diff --git a/packages/demo/components/pages/apis/transaction/builderExample/mintToken.tsx b/packages/demo/components/pages/apis/transaction/builderExample/mintToken.tsx
index 7f2001316..c11179317 100644
--- a/packages/demo/components/pages/apis/transaction/builderExample/mintToken.tsx
+++ b/packages/demo/components/pages/apis/transaction/builderExample/mintToken.tsx
@@ -15,7 +15,7 @@ function Content() {
const codeSnippet = `await mesh
.txIn(txInHash, txInId)
.mintPlutusScriptV2()
- .mint(1, policyId, tokenName)
+ .mint("1", policyId, tokenName)
.mintingScript(mintingScript)
.mintRedeemerValue(mConStr0([]))
.txOut(this.constants.walletAddress, [{ unit: policyId + tokenName, quantity: "1" }])
diff --git a/packages/demo/components/pages/apis/transaction/builderExample/staking.tsx b/packages/demo/components/pages/apis/transaction/builderExample/staking.tsx
new file mode 100644
index 000000000..b604068f7
--- /dev/null
+++ b/packages/demo/components/pages/apis/transaction/builderExample/staking.tsx
@@ -0,0 +1,39 @@
+import Section from '../../../../common/section';
+import Codeblock from '../../../../ui/codeblock';
+
+export default function Staking() {
+ return (
+
+ );
+}
+
+function Content() {
+ const codeSnippet = `const usedAddress = await wallet.getUnusedAddresses();
+const { stakeCredential } = serializeBech32Address(usedAddress[0]);
+await mesh
+ .txIn(txInHash, txInId)
+ .registerStakeCertificate(stakeCredential) // Skip this line if you are not staking for the first time
+ .delegateStakeCertificate(
+ stakeCredential,
+ 'poolxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
+ )
+ .changeAddress(changeAddress)
+ .complete();
+
+const signedTx = mesh.completeSigning()`;
+
+ return (
+ <>
+
+ The following shows a simple example of building a transaction to
+ (register stake certificate and) delegate stake to a pool for the first
+ time.
+
+
+ >
+ );
+}
diff --git a/packages/demo/pages/apis/transaction/builder.tsx b/packages/demo/pages/apis/transaction/builder.tsx
index 7ec1b9b49..0ed81d281 100644
--- a/packages/demo/pages/apis/transaction/builder.tsx
+++ b/packages/demo/pages/apis/transaction/builder.tsx
@@ -5,7 +5,6 @@ import CommonLayout from '../../../components/common/layout';
import InvalidInterval from '../../../components/pages/apis/transaction/builder/InvalidInterval';
import ChangeAddress from '../../../components/pages/apis/transaction/builder/changeAddress';
import Complete from '../../../components/pages/apis/transaction/builder/complete';
-import Schemas from '../../../components/pages/apis/transaction/builder/schemas';
import MetadataValue from '../../../components/pages/apis/transaction/builder/metadataValue';
import MintPlutus from '../../../components/pages/apis/transaction/builder/mintPlutus';
import MintNative from '../../../components/pages/apis/transaction/builder/mintNative';
@@ -18,6 +17,11 @@ import TxInCollateral from '../../../components/pages/apis/transaction/builder/t
import TxOut from '../../../components/pages/apis/transaction/builder/txOut';
import CommonHero from '../../../components/pages/apis/transaction/commonHero';
import Metatags from '../../../components/site/metatags';
+import RegisterCertificate from '../../../components/pages/apis/transaction/builder/registerCertificate';
+import DeregisterCertificate from '../../../components/pages/apis/transaction/builder/deregisterCertificate';
+import DelegateStakeCertificate from '../../../components/pages/apis/transaction/builder/delegateStakeCertificate';
+import RegisterPoolCertificate from '../../../components/pages/apis/transaction/builder/registerPoolCertificate';
+import RetirePoolCertificate from '../../../components/pages/apis/transaction/builder/retirePoolCertificate';
const TransactionBuilderPage: NextPage = () => {
const sidebarItems = [
@@ -56,6 +60,26 @@ const TransactionBuilderPage: NextPage = () => {
label: 'Add metadata',
to: 'metadataValue',
},
+ {
+ label: 'Register Stake Certificate',
+ to: 'registerCertificate',
+ },
+ {
+ label: 'Deregister Stake Certificate',
+ to: 'deregisterCertificate',
+ },
+ {
+ label: 'Delegate Stake',
+ to: 'delegateStakeCertificate',
+ },
+ {
+ label: 'Register Pool Certificate',
+ to: 'registerPoolCertificate',
+ },
+ {
+ label: 'Retire Pool Certificate',
+ to: 'retirePoolCertificate',
+ },
{
label: 'Sign with signing key',
to: 'signingKey',
@@ -64,10 +88,6 @@ const TransactionBuilderPage: NextPage = () => {
label: 'Complete transaction building',
to: 'complete',
},
- {
- label: 'Schemas',
- to: 'schemas',
- },
];
return (
@@ -101,9 +121,13 @@ const TransactionBuilderPage: NextPage = () => {
+
+
+
+
+
-
>
);
diff --git a/packages/demo/pages/apis/transaction/builderExample.tsx b/packages/demo/pages/apis/transaction/builderExample.tsx
index b5b3bac09..6207615f9 100644
--- a/packages/demo/pages/apis/transaction/builderExample.tsx
+++ b/packages/demo/pages/apis/transaction/builderExample.tsx
@@ -12,6 +12,7 @@ import Metatags from '../../../components/site/metatags';
import LockFund from '../../../components/pages/apis/transaction/builderExample/lockFund';
import UnlockFund from '../../../components/pages/apis/transaction/builderExample/unlockFund';
import MintToken from '../../../components/pages/apis/transaction/builderExample/mintToken';
+import Staking from '../../../components/pages/apis/transaction/builderExample/staking';
const TransactionBuilderExamplePage: NextPage = () => {
const sidebarItems = [
@@ -20,6 +21,7 @@ const TransactionBuilderExamplePage: NextPage = () => {
{ label: 'Lock Fund', to: 'lockFund' },
{ label: 'Unlock Fund', to: 'unlockFund' },
{ label: 'Mint Tokens', to: 'mintToken' },
+ { label: 'Delegate Stake', to: 'staking' },
{ label: 'Complex Transaction', to: 'complexTransaction' },
{ label: 'Build without dependency', to: 'withoutDependency' },
{ label: 'Build with object', to: 'withObject' },
@@ -50,6 +52,7 @@ const TransactionBuilderExamplePage: NextPage = () => {
+
diff --git a/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts b/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts
index 160e4a3a3..1a3b8251a 100644
--- a/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts
+++ b/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts
@@ -12,6 +12,7 @@ import {
Quantity,
UTxO,
Unit,
+ PoolParams,
} from '@mesh/common/types';
import {
buildTxBuilder,
@@ -19,6 +20,7 @@ import {
toPlutusData,
toAddress,
buildDataCost,
+ toRelay,
} from '@mesh/common/utils';
import { csl } from '@mesh/core';
import {
@@ -34,6 +36,8 @@ import {
ValidityRange,
Metadata,
BuilderData,
+ Certificate,
+ TxInParameter,
} from './type';
import { selectUtxos } from '@mesh/core/CPS-009';
@@ -93,6 +97,7 @@ export class MeshTxBuilderCore {
changeAddress: '',
metadata: [],
validityRange: {},
+ certificates: [],
signingKey: [],
});
@@ -140,6 +145,7 @@ export class MeshTxBuilderCore {
referenceInputs,
mints,
changeAddress,
+ certificates,
validityRange,
requiredSignatures,
metadata,
@@ -161,6 +167,8 @@ export class MeshTxBuilderCore {
this.addUtxosFrom(extraInputs, String(selectionThreshold));
}
+ this.removeDuplicateInputs();
+
this.meshTxBuilderBody.mints.sort((a, b) =>
a.policyId.localeCompare(b.policyId)
);
@@ -177,6 +185,7 @@ export class MeshTxBuilderCore {
this.addAllCollaterals(collaterals);
this.addAllReferenceInputs(referenceInputs);
this.addAllMints(mints);
+ this.addAllCertificates(certificates);
this.addValidityRange(validityRange);
this.addAllRequiredSignatures(requiredSignatures);
this.addAllMetadata(metadata);
@@ -192,7 +201,7 @@ export class MeshTxBuilderCore {
)
.reduce((acc, curr) => acc + parseInt(curr), 0);
- const collateralEsimate = Math.ceil(
+ const collateralEstimate = Math.ceil(
(this._protocolParams.collateralPercent *
Number(
Number(
@@ -207,14 +216,14 @@ export class MeshTxBuilderCore {
let collateralReturnNeeded = false;
- if (totalCollateral - collateralEsimate > 0) {
+ if (totalCollateral - collateralEstimate > 0) {
const collateralEstimateOutput = csl.TransactionOutput.new(
csl.Address.from_bech32(changeAddress),
- csl.Value.new(csl.BigNum.from_str(String(collateralEsimate)))
+ csl.Value.new(csl.BigNum.from_str(String(collateralEstimate)))
);
if (
- totalCollateral - collateralEsimate >
+ totalCollateral - collateralEstimate >
Number(
csl
.min_ada_for_output(
@@ -639,7 +648,7 @@ export class MeshTxBuilderCore {
* @param name The hex of token name of the asset to be minted
* @returns The MeshTxBuilder instance
*/
- mint = (quantity: number, policy: string, name: string) => {
+ mint = (quantity: string, policy: string, name: string) => {
if (this.mintItem) {
this.queueMint();
}
@@ -798,6 +807,76 @@ export class MeshTxBuilderCore {
return this;
};
+ /**
+ * Creates a pool registration certificate, and adds it to the transaction
+ * @param poolParams Parameters for pool registration
+ * @returns The MeshTxBuilder instance
+ */
+ registerPoolCertificate = (poolParams: PoolParams) => {
+ this.meshTxBuilderBody.certificates.push({
+ type: 'RegisterPool',
+ poolParams,
+ });
+ return this;
+ };
+
+ /**
+ * Creates a stake registration certificate, and adds it to the transaction
+ * @param stakeKeyHash The keyHash of the stake key
+ * @returns The MeshTxBuilder instance
+ */
+ registerStakeCertificate = (stakeKeyHash: string) => {
+ this.meshTxBuilderBody.certificates.push({
+ type: 'RegisterStake',
+ stakeKeyHash,
+ });
+ return this;
+ };
+
+ /**
+ * Creates a stake delegation certificate, and adds it to the transaction
+ * This will delegate stake from the corresponding stake address to the pool
+ * @param stakeKeyHash The keyHash of the stake key
+ * @param poolId poolId can be in either bech32 or hex form
+ * @returns The MeshTxBuilder instance
+ */
+ delegateStakeCertificate = (stakeKeyHash: string, poolId: string) => {
+ this.meshTxBuilderBody.certificates.push({
+ type: 'DelegateStake',
+ stakeKeyHash,
+ poolId,
+ });
+ return this;
+ };
+
+ /**
+ * Creates a stake deregister certificate, and adds it to the transaction
+ * @param stakeKeyHash The keyHash of the stake key
+ * @returns The MeshTxBuilder instance
+ */
+ deregisterStakeCertificate = (stakeKeyHash: string) => {
+ this.meshTxBuilderBody.certificates.push({
+ type: 'DeregisterStake',
+ stakeKeyHash,
+ });
+ return this;
+ };
+
+ /**
+ * Creates a pool retire certificate, and adds it to the transaction
+ * @param poolId poolId can be in either bech32 or hex form
+ * @param epoch The intended epoch to retire the pool
+ * @returns The MeshTxBuilder instance
+ */
+ retirePoolCertificate = (poolId: string, epoch: number) => {
+ this.meshTxBuilderBody.certificates.push({
+ type: 'RetirePool',
+ poolId,
+ epoch,
+ });
+ return this;
+ };
+
/**
* Configure the address to accept change UTxO
* @param addr The address to accept change UTxO
@@ -1000,6 +1079,23 @@ export class MeshTxBuilderCore {
// Below protected functions for completing tx building
+ protected removeDuplicateInputs = () => {
+ const inputs = this.meshTxBuilderBody.inputs;
+ const getTxInId = (txIn: TxInParameter): string => {
+ return `${txIn.txHash}#${txIn.txIndex}`;
+ };
+ const addedInputs: string[] = [];
+ for (let i = 0; i < inputs.length; i++) {
+ const currentTxInId = getTxInId(inputs[i].txIn);
+ if (addedInputs.includes(currentTxInId)) {
+ inputs.splice(i, 1);
+ i--;
+ } else {
+ addedInputs.push(currentTxInId);
+ }
+ }
+ };
+
private addAllInputs = (inputs: TxIn[]) => {
for (let i = 0; i < inputs.length; i++) {
const currentTxIn = inputs[i]; //TODO: add type
@@ -1236,7 +1332,7 @@ export class MeshTxBuilderCore {
mintBuilder.add_asset(
csl.MintWitness.new_plutus_script(script, newRedeemer),
csl.AssetName.new(Buffer.from(assetName, 'hex')),
- csl.Int.new_i32(amount)
+ csl.Int.new(csl.BigNum.from_str(amount))
);
};
@@ -1251,10 +1347,116 @@ export class MeshTxBuilderCore {
csl.NativeScript.from_hex(scriptSource.script.code)
),
csl.AssetName.new(Buffer.from(assetName, 'hex')),
- csl.Int.new_i32(amount)
+ csl.Int.new(csl.BigNum.from_str(amount))
);
};
+ private decimalToFraction(
+ decimal: number
+ ): [numerator: number, denominator: number] {
+ const powerOf10 = 10 ** decimal.toString().split('.')[1].length;
+ const numerator = decimal * powerOf10;
+ const denominator = powerOf10;
+
+ return [numerator, denominator];
+ }
+
+ private toPoolParams = (poolParams: PoolParams): csl.PoolParams => {
+ const marginFraction = this.decimalToFraction(poolParams.margin);
+ const relays = csl.Relays.new();
+ poolParams.relays.forEach((relay) => {
+ relays.add(toRelay(relay));
+ });
+ const rewardAddress = csl.RewardAddress.from_address(
+ csl.Address.from_bech32(poolParams.rewardAddress)
+ );
+ if (rewardAddress === undefined) {
+ throw new Error('Reward address is invalid');
+ }
+ const poolOwners = csl.Ed25519KeyHashes.new();
+ poolParams.owners.forEach((owner) => {
+ poolOwners.add(csl.Ed25519KeyHash.from_hex(owner));
+ });
+ return csl.PoolParams.new(
+ csl.Ed25519KeyHash.from_hex(poolParams.operator),
+ csl.VRFKeyHash.from_hex(poolParams.VRFKeyHash),
+ csl.BigNum.from_str(poolParams.pledge),
+ csl.BigNum.from_str(poolParams.cost),
+ csl.UnitInterval.new(
+ csl.BigNum.from_str(marginFraction[0].toString()),
+ csl.BigNum.from_str(marginFraction[1].toString())
+ ),
+ rewardAddress,
+ poolOwners,
+ relays,
+ poolParams.metadata
+ ? csl.PoolMetadata.from_json(JSON.stringify(poolParams.metadata))
+ : undefined
+ );
+ };
+
+ private addCertificate = (
+ certificates: csl.Certificates,
+ cert: Certificate
+ ) => {
+ switch (cert.type) {
+ case 'RegisterPool':
+ certificates.add(
+ csl.Certificate.new_pool_registration(
+ csl.PoolRegistration.new(this.toPoolParams(cert.poolParams))
+ )
+ );
+ break;
+ case 'RegisterStake':
+ certificates.add(
+ csl.Certificate.new_stake_registration(
+ csl.StakeRegistration.new(
+ csl.StakeCredential.from_keyhash(
+ csl.Ed25519KeyHash.from_hex(cert.stakeKeyHash)
+ )
+ )
+ )
+ );
+ break;
+ case 'DelegateStake':
+ certificates.add(
+ csl.Certificate.new_stake_delegation(
+ csl.StakeDelegation.new(
+ csl.StakeCredential.from_keyhash(
+ csl.Ed25519KeyHash.from_hex(cert.stakeKeyHash)
+ ),
+ cert.poolId.startsWith('pool')
+ ? csl.Ed25519KeyHash.from_bech32(cert.poolId)
+ : csl.Ed25519KeyHash.from_hex(cert.poolId)
+ )
+ )
+ );
+ break;
+ case 'DeregisterStake':
+ certificates.add(
+ csl.Certificate.new_stake_deregistration(
+ csl.StakeDeregistration.new(
+ csl.StakeCredential.from_keyhash(
+ csl.Ed25519KeyHash.from_hex(cert.stakeKeyHash)
+ )
+ )
+ )
+ );
+ break;
+ case 'RetirePool':
+ certificates.add(
+ csl.Certificate.new_pool_retirement(
+ csl.PoolRetirement.new(
+ cert.poolId.startsWith('pool')
+ ? csl.Ed25519KeyHash.from_bech32(cert.poolId)
+ : csl.Ed25519KeyHash.from_hex(cert.poolId),
+ cert.epoch
+ )
+ )
+ );
+ }
+ };
+
protected queueAllLastItem = () => {
if (this.txOutput) {
this.meshTxBuilderBody.outputs.push(this.txOutput);
@@ -1272,6 +1474,14 @@ export class MeshTxBuilderCore {
}
};
+ protected addAllCertificates = (allCertificates: Certificate[]) => {
+ const certificates = csl.Certificates.new();
+ allCertificates.forEach((cert) => {
+ this.addCertificate(certificates, cert);
+ });
+ this.txBuilder.set_certs(certificates);
+ };
+
protected addCostModels = () => {
this.txBuilder.calc_script_data_hash(
csl.TxBuilderConstants.plutus_vasil_cost_models()
diff --git a/packages/module/src/transaction/meshTxBuilder/progress.md b/packages/module/src/transaction/meshTxBuilder/progress.md
deleted file mode 100644
index 3a87ce424..000000000
--- a/packages/module/src/transaction/meshTxBuilder/progress.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# Progress of Lower Level API - MeshTxBuilder
-
-## Core Apis
-
-| Method Name | Sync | cli | Tested | Remarks |
-| --------------------------------------- | ---- | --- | ------ | ------------------------------------- |
-| txIn | X | X | X | |
-| txInDatumValue | | | | |
-| txInInlineDatumPresent | X | X | X | |
-| txOut | X | X | X | automate minUTxO not tested |
-| txOutDatumHashValue | | | | |
-| txOutInlineDatumValue | X | X | X | |
-| txOutReferenceScript | X | X | | |
-| spendingPlutusScriptV2 | X | X | X | |
-| spendingTxInReference | X | X | X | |
-| spendingReferenceTxInInlineDatumPresent | X | X | X | Identical with txInInlineDatumPresent |
-| spendingReferenceTxInRedeemerValue | X | X | X | |
-| readOnlyTxInReference | X | X | X | |
-| mintPlutusScriptV2 | X | X | X | |
-| mint | X | X | X | |
-| mintTxInReference | X | X | X | |
-| mintRedeemerValue | X | X | X | |
-| mintReferenceTxInRedeemerValue | X | X | X | |
-| requiredSignerHash | X | X | X | |
-| txInCollateral | X | X | X | |
-| changeAddress | X | X | X | Collateral return is not tested |
-| invalidBefore | X | X | | |
-| invalidHereafter | X | X | | |
-| metadataValue | X | X | X | |
-| signingKey | X | X | X | |
-| complete | | | | TODO: EvaluateTx / Collateral returns |
-| getUTxOInfo | X | X | X | |
-| protocolParams | X | X | X | |
-
-## Other Tasks
-
-- Add collateral return
-- Completing Apis
- - Staking related apis
-
-## Higher Level refactor plan
-
-- UTxO selection
-- Expose the `txBuilder`
-- Migrating to lower level apis if any
-- Removing redundant operations (make it using MeshTxBuilderCore's methods)
diff --git a/packages/module/src/transaction/meshTxBuilder/type.ts b/packages/module/src/transaction/meshTxBuilder/type.ts
index 65f75909d..cf951415d 100644
--- a/packages/module/src/transaction/meshTxBuilder/type.ts
+++ b/packages/module/src/transaction/meshTxBuilder/type.ts
@@ -5,6 +5,7 @@ import {
LanguageVersion,
PlutusScript,
UTxO,
+ PoolParams,
} from '@mesh/common/types';
export type MeshTxBuilderBody = {
@@ -19,7 +20,7 @@ export type MeshTxBuilderBody = {
changeAddress: string;
metadata: Metadata[];
validityRange: ValidityRange;
- // certificates?: Certificate[];
+ certificates: Certificate[];
// withdrawals?: Record;
signingKey: string[];
};
@@ -87,7 +88,7 @@ export type MintItem = {
type: 'Plutus' | 'Native';
policyId: string;
assetName: string;
- amount: number;
+ amount: string;
redeemer?: Redeemer;
scriptSource?:
| {
@@ -135,6 +136,13 @@ export type Metadata = {
metadata: object;
};
+export type Certificate =
+ | { type: 'RegisterPool'; poolParams: PoolParams }
+ | { type: 'RegisterStake'; stakeKeyHash: string }
+ | { type: 'DelegateStake'; stakeKeyHash: string, poolId: string }
+ | { type: 'DeregisterStake'; stakeKeyHash: string }
+ | { type: 'RetirePool'; poolId: string; epoch: number };
+
// Utilities
export type RequiredWith = Required &