Skip to content

Commit

Permalink
Test Atomic Swap Nominal Use Case
Browse files Browse the repository at this point in the history
  • Loading branch information
nhenin committed Jan 15, 2024
1 parent db2f342 commit 8a3b78f
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 124 deletions.
67 changes: 40 additions & 27 deletions packages/language/examples/src/atomicSwap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ import {
datetoTimeout,
} from "@marlowe.io/language-core-v1";
import * as G from "@marlowe.io/language-core-v1/guards";

export type IReduce = void;
const iReduce: void = undefined;
import { SingleInputTx } from "@marlowe.io/language-core-v1/transaction.js";

/**
* Atomic Swap Scheme, canonical information to define the contract.
Expand Down Expand Up @@ -160,7 +158,6 @@ export type ActionParticipant = "buyer" | "seller" | "anybody";
export type RetrieveMinimumLovelaceAdded = {
typeName: "RetrieveMinimumLovelaceAdded";
owner: ActionParticipant;
input: IReduce;
};

export type ProvisionOffer = {
Expand Down Expand Up @@ -207,14 +204,31 @@ export type Swapped = { typeName: "Swapped" };

/* #endregion */

export class UnexpectedSwapContractState extends Error {
public type = "UnexpectedSwapContractState" as const;
export class UnexpectedActiveSwapContractState extends Error {
public type = "UnexpectedActiveSwapContractState" as const;
public scheme: Scheme;
public state?: MarloweState;
constructor(scheme: Scheme, state?: MarloweState) {
super("Swap Contract / Unexpected State");
public state: MarloweState;
public inputHistory: SingleInputTx[];
constructor(
scheme: Scheme,
inputHistory: SingleInputTx[],
state: MarloweState
) {
super("Swap Contract / Unexpected Active State");
this.scheme = scheme;
this.state = state;
this.inputHistory = inputHistory;
}
}

export class UnexpectedClosedSwapContractState extends Error {
public type = "UnexpectedClosedSwapContractState" as const;
public scheme: Scheme;
public inputHistory: SingleInputTx[];
constructor(scheme: Scheme, inputHistory: SingleInputTx[]) {
super("Swap Contract / Unexpected closed State");
this.scheme = scheme;
this.inputHistory = inputHistory;
}
}

Expand All @@ -241,7 +255,6 @@ export const getAvailableActions = (
{
typeName: "RetrieveMinimumLovelaceAdded",
owner: "anybody",
input: iReduce,
},
];
case "WaitingForAnswer":
Expand Down Expand Up @@ -281,7 +294,7 @@ export const getAvailableActions = (

export const getState = (
scheme: Scheme,
inputHistory: Input[],
inputHistory: SingleInputTx[],
state?: MarloweState
): State => {
return state
Expand All @@ -291,7 +304,7 @@ export const getState = (

export const getClosedState = (
scheme: Scheme,
inputHistory: Input[]
inputHistory: SingleInputTx[]
): Closed => {
switch (inputHistory.length) {
// Offer Provision Deadline has passed and there is one reduced applied to close the contract
Expand All @@ -307,10 +320,10 @@ export const getClosedState = (
};
case 2: {
const isRetracted =
G.IChoice.is(inputHistory[1]) &&
inputHistory[1].for_choice_id.choice_name == "retract";
const nbDeposits = inputHistory.filter((input) =>
G.IDeposit.is(input)
G.IChoice.is(inputHistory[1].input) &&
inputHistory[1].input.for_choice_id.choice_name == "retract";
const nbDeposits = inputHistory.filter((singleInputTx) =>
G.IDeposit.is(singleInputTx.input)
).length;
if (isRetracted && nbDeposits === 1) {
return {
Expand All @@ -327,11 +340,11 @@ export const getClosedState = (
break;
}
case 3: {
const nbDeposits = inputHistory.filter((input) =>
G.IDeposit.is(input)
const nbDeposits = inputHistory.filter((singleInputTx) =>
G.IDeposit.is(singleInputTx.input)
).length;
const nbNotify = inputHistory.filter((input) =>
G.INotify.is(input)
const nbNotify = inputHistory.filter((singleInputTx) =>
G.INotify.is(singleInputTx.input)
).length;
if (nbDeposits === 2 && nbNotify === 1) {
return {
Expand All @@ -341,12 +354,12 @@ export const getClosedState = (
}
}
}
throw new UnexpectedSwapContractState(scheme);
throw new UnexpectedClosedSwapContractState(scheme, inputHistory);
};

export const getActiveState = (
scheme: Scheme,
inputHistory: Input[],
inputHistory: SingleInputTx[],
state: MarloweState
): ActiveState => {
const now: Timeout = datetoTimeout(new Date());
Expand All @@ -361,8 +374,8 @@ export const getActiveState = (
}
break;
case 2: {
const nbDeposits = inputHistory.filter((input) =>
G.IDeposit.is(input)
const nbDeposits = inputHistory.filter((singleInputTx) =>
G.IDeposit.is(singleInputTx.input)
).length;
if (nbDeposits === 2 && now < scheme.swapConfirmation.deadline) {
return { typeName: "WaitingForSwapConfirmation" };
Expand All @@ -371,7 +384,7 @@ export const getActiveState = (
}
}

throw new UnexpectedSwapContractState(scheme, state);
throw new UnexpectedActiveSwapContractState(scheme, inputHistory, state);
};

export function mkContract(scheme: Scheme): Contract {
Expand Down Expand Up @@ -408,12 +421,12 @@ export function mkContract(scheme: Scheme): Contract {
pay: scheme.offer.asset.amount,
token: scheme.offer.asset.token,
from_account: scheme.offer.seller,
to: { party: scheme.ask.buyer },
to: { account: scheme.ask.buyer },
then: {
pay: scheme.ask.asset.amount,
token: scheme.ask.asset.token,
from_account: scheme.ask.buyer,
to: { party: scheme.offer.seller },
to: { account: scheme.offer.seller },
then: confirmSwap,
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export const useMintedRoles = (
: (policyId as UsePolicyWithClosedRoleTokens);

/**
* Configure the minting of a Closed Role Token.
* Configure the minting of a Role Token.
* @param openness where to distribute the token (Either openly or closedly)
* @param quantity Quantity of the Closed Role Token (by Default an NFT (==1))
* @param metadata Token Metadata of the Token
Expand Down
1 change: 1 addition & 0 deletions packages/runtime/lifecycle/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ export interface PayoutsAPI {
*/
available(filters?: Filters): Promise<PayoutAvailable[]>;

// TODO : Withdraw should not `waitConfirmation` behind the scene and it should return a `TxId` (https://github.com/input-output-hk/marlowe-ts-sdk/issues/170)
/**
* TODO: comment
* @throws DecodingError
Expand Down
Loading

0 comments on commit 8a3b78f

Please sign in to comment.