Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making deposit calldata generation optional #1319

Merged
merged 7 commits into from
Feb 16, 2025
Merged
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
62 changes: 29 additions & 33 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 @@ -165,17 +171,17 @@ impl DotrainOrderGui {
) -> Result<ApprovalCalldataResult, GuiError> {
let deployment = self.get_current_deployment()?;
self.check_select_tokens()?;
self.check_deposits()?;

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

let calldatas = self
.dotrain_order
.generate_approval_calldatas(
&deployment.key,
&owner,
&self.get_deposits_as_map().await?,
)
.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 @@ -206,7 +212,6 @@ impl DotrainOrderGui {
pub async fn generate_deposit_calldatas(&mut self) -> Result<DepositCalldataResult, GuiError> {
let deployment = self.get_current_deployment()?;
self.check_select_tokens()?;
self.check_deposits()?;
self.populate_vault_ids(&deployment)?;
let deployment = self.get_current_deployment()?;

Expand All @@ -228,11 +233,17 @@ impl DotrainOrderGui {
Ok(((vault_id, token.address), *amount))
})
.collect::<Result<HashMap<_, _>, GuiError>>()?;

if token_deposits.is_empty() {
return Ok(DepositCalldataResult::NoDeposits);
}

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

Ok(DepositCalldataResult::Calldatas(calldatas))
}

/// Generate add order calldata
Expand Down Expand Up @@ -260,42 +271,27 @@ impl DotrainOrderGui {
) -> Result<DepositAndAddOrderCalldataResult, GuiError> {
let deployment = self.get_current_deployment()?;
self.check_select_tokens()?;
self.check_deposits()?;
self.check_field_values()?;
self.populate_vault_ids(&deployment)?;
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 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
77 changes: 27 additions & 50 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 All @@ -1144,44 +1159,6 @@ ${dotrainWithoutVaultIds}`;
assert.equal(missingFieldValues[0], 'Test binding');
});

it('should throw error if deposit value not set', async () => {
await mockServer
.forPost('/rpc-url')
.once()
.withBodyIncluding('0x82ad56cb')
.thenSendJsonRpcResult(
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000007546f6b656e203100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000025431000000000000000000000000000000000000000000000000000000000000'
);
await mockServer
.forPost('/rpc-url')
.once()
.withBodyIncluding('0x82ad56cb')
.thenSendJsonRpcResult(
'0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000754656b656e203200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000025432000000000000000000000000000000000000000000000000000000000000'
);

let testDotrain = `${guiConfig2}

${dotrainWithoutVaultIds}`;
let gui = await DotrainOrderGui.chooseDeployment(testDotrain, 'other-deployment');

await expect(
async () =>
await gui.generateApprovalCalldatas('0x1234567890abcdef1234567890abcdef12345678')
).rejects.toThrow('Missing deposit with token: T1');
await expect(async () => await gui.generateDepositCalldatas()).rejects.toThrow(
'Missing deposit with token: T1'
);
await expect(async () => await gui.generateDepositAndAddOrderCalldatas()).rejects.toThrow(
'Missing deposit with token: T1'
);

let missingDeposits = gui.getMissingDeposits();
assert.equal(missingDeposits.length, 2);
assert.equal(missingDeposits[0], 'token1');
assert.equal(missingDeposits[1], 'token2');
});

it('should set vault ids', async () => {
mockServer
.forPost('/rpc-url')
Expand Down Expand Up @@ -1250,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
Loading