Skip to content

Commit

Permalink
enum, tests and front end
Browse files Browse the repository at this point in the history
  • Loading branch information
hardyjosh committed Feb 16, 2025
1 parent 9e44b05 commit af635ee
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 70 deletions.
63 changes: 27 additions & 36 deletions crates/js_api/src/gui/order_operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ pub struct AllowancesResult(Vec<TokenAllowance>);
impl_all_wasm_traits!(AllowancesResult);

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)]
pub struct ApprovalCalldataResult(Vec<dotrain_order::calldata::ApprovalCalldata>);
pub enum ApprovalCalldataResult {
NoDeposits,
Calldatas(Vec<dotrain_order::calldata::ApprovalCalldata>),
}
impl_all_wasm_traits!(ApprovalCalldataResult);

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)]
pub struct DepositCalldataResult(Vec<Bytes>);
pub enum DepositCalldataResult {
NoDeposits,
Calldatas(Vec<Bytes>),
}
impl_all_wasm_traits!(DepositCalldataResult);

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Tsify)]
Expand Down Expand Up @@ -167,15 +173,15 @@ impl DotrainOrderGui {
self.check_select_tokens()?;

let deposits_map = self.get_deposits_as_map().await?;
if deposits_map.len() == 0 {
return Ok(ApprovalCalldataResult(Vec::new()));
if deposits_map.is_empty() {
return Ok(ApprovalCalldataResult::NoDeposits);
}

let calldatas = self
.dotrain_order
.generate_approval_calldatas(&deployment.key, &owner, &deposits_map)
.await?;
Ok(ApprovalCalldataResult(calldatas))
Ok(ApprovalCalldataResult::Calldatas(calldatas))
}

fn populate_vault_ids(&mut self, deployment: &GuiDeployment) -> Result<(), GuiError> {
Expand Down Expand Up @@ -228,14 +234,16 @@ impl DotrainOrderGui {
})
.collect::<Result<HashMap<_, _>, GuiError>>()?;

let mut calldatas = Vec::new();
if token_deposits.len() > 0 {
calldatas = self
.dotrain_order
.generate_deposit_calldatas(&deployment.key, &token_deposits)
.await?;
if token_deposits.is_empty() {
return Ok(DepositCalldataResult::NoDeposits);
}
Ok(DepositCalldataResult(calldatas))

let calldatas = self
.dotrain_order
.generate_deposit_calldatas(&deployment.key, &token_deposits)
.await?;

Ok(DepositCalldataResult::Calldatas(calldatas))
}

/// Generate add order calldata
Expand Down Expand Up @@ -268,39 +276,22 @@ impl DotrainOrderGui {
self.update_bindings(&deployment)?;
let deployment = self.get_current_deployment()?;

let token_deposits = self
.get_vaults_and_deposits(&deployment)
.await?
.iter()
.enumerate()
.map(|(i, (order_io, amount))| {
let vault_id = order_io
.vault_id
.ok_or(GuiError::VaultIdNotFound(i.to_string()))?;
let mut calls = Vec::new();

if order_io.token.is_none() {
return Err(GuiError::SelectTokensNotSet);
}
let token = order_io.token.as_ref().unwrap();
let deposit_calldatas = self.generate_deposit_calldatas().await?;

Ok(((vault_id, token.address), *amount))
})
.collect::<Result<HashMap<_, _>, GuiError>>()?;
let deposit_calldatas = match deposit_calldatas {
DepositCalldataResult::Calldatas(calldatas) => calldatas,
DepositCalldataResult::NoDeposits => Vec::new(),
};

let mut calls = Vec::new();
let mut deposit_calldatas = Vec::new();
if token_deposits.len() > 0 {
deposit_calldatas = self
.dotrain_order
.generate_deposit_calldatas(&deployment.key, &token_deposits)
.await?;
}
let add_order_calldata = self
.dotrain_order
.generate_add_order_calldata(&deployment.key)
.await?;

calls.push(Bytes::copy_from_slice(&add_order_calldata));

for calldata in deposit_calldatas.iter() {
calls.push(Bytes::copy_from_slice(calldata));
}
Expand Down
39 changes: 27 additions & 12 deletions packages/orderbook/test/js_api/gui.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ describe('Rain Orderbook JS API Package Bindgen Tests - Gui', async function ()
.once()
.withBodyIncluding('0x82ad56cb')
.thenSendJsonRpcResult(
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000754656b656e203200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000025432000000000000000000000000000000000000000000000000000000000000'
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000754656b656e203200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000025432000000000000000000000000000000000000000000000000000000000000'
);
dotrain3 = `${guiConfig3}
Expand Down Expand Up @@ -887,16 +887,24 @@ ${dotrainWithoutVaultIds}
gui.saveDeposit('token1', '1000');
gui.saveDeposit('token2', '5000');

const approvalCalldatas: ApprovalCalldataResult = await gui.generateApprovalCalldatas(
const result = await gui.generateApprovalCalldatas(
'0x1234567890abcdef1234567890abcdef12345678'
);
assert.equal(approvalCalldatas.length, 1);
assert.equal(approvalCalldatas[0].token, '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063');
// 5000 - 1000 = 4000 * 10^18

assert.equal(result.Calldatas.length, 1);
assert.equal(result.Calldatas[0].token, '0x8f3cf7ad23cd3cadbd9735aff958023239c6a063');
assert.equal(
approvalCalldatas[0].calldata,
result.Calldatas[0].calldata,
'0x095ea7b3000000000000000000000000c95a5f8efe14d7a20bd2e5bafec4e71f8ce0b9a600000000000000000000000000000000000000000000010f0cf064dd59200000'
);

// Test no deposits case
gui.removeDeposit('token1');
gui.removeDeposit('token2');
const emptyResult = await gui.generateApprovalCalldatas(
'0x1234567890abcdef1234567890abcdef12345678'
);
assert.equal(emptyResult, 'NoDeposits');
});

it('generates deposit calldatas', async () => {
Expand Down Expand Up @@ -926,12 +934,19 @@ ${dotrainWithoutVaultIds}
gui.saveDeposit('token1', '1000');
gui.saveDeposit('token2', '5000');

const depositCalldatas: DepositCalldataResult = await gui.generateDepositCalldatas();
assert.equal(depositCalldatas.length, 1);
const result = await gui.generateDepositCalldatas();

assert.equal(result.Calldatas.length, 1);
assert.equal(
depositCalldatas[0],
result.Calldatas[0],
'0x91337c0a0000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000010f0cf064dd5920000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000'
);

// Test no deposits case
gui.removeDeposit('token1');
gui.removeDeposit('token2');
const emptyResult = await gui.generateDepositCalldatas();
assert.equal(emptyResult, 'NoDeposits');
});

it('generates add order calldata', async () => {
Expand Down Expand Up @@ -1035,7 +1050,7 @@ ${dotrainWithoutVaultIds}
.once()
.withBodyIncluding('0x82ad56cb')
.thenSendJsonRpcResult(
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000754656b656e203200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000025432000000000000000000000000000000000000000000000000000000000000'
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000754656b656e203200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000025432000000000000000000000000000000000000000000000000000000000000'
);

let testDotrain = `${guiConfig2}
Expand Down Expand Up @@ -1121,7 +1136,7 @@ ${dotrainWithoutVaultIds}`;
.once()
.withBodyIncluding('0x82ad56cb')
.thenSendJsonRpcResult(
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000754656b656e203200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000025432000000000000000000000000000000000000000000000000000000000000'
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000754656b656e203200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000025432000000000000000000000000000000000000000000000000000000000000'
);

let testDotrain = `${guiConfig2}
Expand Down Expand Up @@ -1212,7 +1227,7 @@ ${dotrainWithoutVaultIds}`;
gui.saveDeposit('token1', '0');
gui.saveDeposit('token2', '0');
const calldatas = await gui.generateDepositCalldatas();
assert.equal(calldatas.length, 0);
assert.equal(calldatas.Calldatas.length, 0);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { Config } from '@wagmi/core';
import { getAccount } from '@wagmi/core';
import type {
ApprovalCalldataResult,
DepositAndAddOrderCalldataResult,
DotrainOrderGui
} from '@rainlanguage/orderbook/js_api';
import type { OrderIO } from '@rainlanguage/orderbook/js_api';
import type { Hex } from 'viem';
import type { ExtendedApprovalCalldata } from '$lib/stores/transactionStore';

export enum AddOrderErrors {
ADD_ORDER_FAILED = 'Failed to add order',
Expand All @@ -21,7 +21,7 @@ export enum AddOrderErrors {
}

export interface HandleAddOrderResult {
approvals: ApprovalCalldataResult;
approvals: ExtendedApprovalCalldata[];
deploymentCalldata: DepositAndAddOrderCalldataResult;
orderbookAddress: Hex;
chainId: number;
Expand All @@ -45,9 +45,9 @@ export async function getDeploymentTransactionArgs(
throw new Error(AddOrderErrors.NO_WALLET);
}

let approvals;
let approvalResults;
try {
approvals = await gui.generateApprovalCalldatas(address);
approvalResults = await gui.generateApprovalCalldatas(address);
} catch (error) {
throw new Error(
`${AddOrderErrors.APPROVAL_FAILED}: ${error instanceof Error ? error.message : 'Unknown error'}`
Expand Down Expand Up @@ -75,6 +75,8 @@ export async function getDeploymentTransactionArgs(
throw new Error(AddOrderErrors.MISSING_ORDERBOOK);
}

let approvals: ExtendedApprovalCalldata[] = [];

try {
const outputTokenInfos = await Promise.all(
allTokenOutputs.map((token) => {
Expand All @@ -84,16 +86,18 @@ export async function getDeploymentTransactionArgs(
})
);

approvals = approvals.map((approval) => {
const token = outputTokenInfos.find((token) => token?.address === approval.token);
if (!token) {
throw new Error(`Token info not found for address: ${approval.token}`);
}
return {
...approval,
symbol: token.symbol
};
});
if (approvalResults != 'NoDeposits') {
approvals = approvalResults.Calldatas.map((approval) => {
const token = outputTokenInfos.find((token) => token?.address === approval.token);
if (!token) {
throw new Error(`Token info not found for address: ${approval.token}`);
}
return {
...approval,
symbol: token.symbol
};
});
}
} catch (error) {
throw new Error(
`${AddOrderErrors.TOKEN_INFO_FAILED}: ${error instanceof Error ? error.message : 'Unknown error'}`
Expand Down
3 changes: 2 additions & 1 deletion packages/ui-components/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export type { ConfigSource, OrderbookConfigSource, OrderbookRef } from './typesh
export {
TransactionStatus,
TransactionErrorMessage,
type TransactionState
type TransactionState,
type ExtendedApprovalCalldata
} from './stores/transactionStore';
export type { DeploymentArgs } from './types/transaction';

Expand Down
2 changes: 1 addition & 1 deletion packages/ui-components/src/lib/stores/transactionStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export enum TransactionErrorMessage {
REMOVE_ORDER_FAILED = 'Failed to remove order.'
}

type ExtendedApprovalCalldata = ApprovalCalldata & { symbol?: string };
export type ExtendedApprovalCalldata = ApprovalCalldata & { symbol?: string };

export type DeploymentTransactionArgs = {
config: Config;
Expand Down
9 changes: 3 additions & 6 deletions packages/webapp/src/lib/components/DeployModal.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<script lang="ts">
import { transactionStore } from '@rainlanguage/ui-components';
import { transactionStore, type ExtendedApprovalCalldata } from '@rainlanguage/ui-components';
import type { Hex } from 'viem';
import type {
ApprovalCalldataResult,
DepositAndAddOrderCalldataResult
} from '@rainlanguage/orderbook/js_api';
import type { DepositAndAddOrderCalldataResult } from '@rainlanguage/orderbook/js_api';
import { wagmiConfig } from '$lib/stores/wagmi';
import TransactionModal from './TransactionModal.svelte';
export let open: boolean = false;
export let approvals: ApprovalCalldataResult;
export let approvals: ExtendedApprovalCalldata[];
export let deploymentCalldata: DepositAndAddOrderCalldataResult;
export let orderbookAddress: Hex;
export let chainId: number;
Expand Down

0 comments on commit af635ee

Please sign in to comment.