Skip to content

Commit

Permalink
WASM Move Calls (#1499)
Browse files Browse the repository at this point in the history
Implement TsMoveCalls
  • Loading branch information
UMR1352 authored Jan 24, 2025
1 parent ca1e3f2 commit c3d5f09
Show file tree
Hide file tree
Showing 28 changed files with 1,831 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .github/actions/rust/sccache/setup-sccache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ runs:
if: inputs.os == 'macos-latest'
shell: bash
run: |
brew update --preinstall
brew update --auto-update
brew install sccache
- name: Install sccache (ubuntu-24.04)
Expand Down
1 change: 1 addition & 0 deletions bindings/wasm/iota_interaction_ts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
anyhow = "1.0.75"
async-trait = { version = "0.1", default-features = false }
bcs = "0.1.6"
bls12_381_plus = "0.8.17"
cfg-if = "1.0.0"
console_error_panic_hook = { version = "0.1" }
Expand Down
4 changes: 4 additions & 0 deletions bindings/wasm/iota_interaction_ts/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright 2020-2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

export * as move_calls from "./move_calls";
27 changes: 27 additions & 0 deletions bindings/wasm/iota_interaction_ts/lib/move_calls/asset/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { Transaction } from "@iota/iota.js/transactions";

export function create(
inner_bytes: Uint8Array,
inner_type: string,
mutable: boolean,
transferable: boolean,
deletable: boolean,
packageId: string,
): Promise<Uint8Array> {
const tx = new Transaction();
const inner_arg = tx.pure(inner_bytes);
const mutableArg = tx.pure.bool(mutable);
const transferableArg = tx.pure.bool(transferable);
const deletableArg = tx.pure.bool(deletable);

tx.moveCall({
target: `${packageId}::asset::new_with_config`,
typeArguments: [inner_type],
arguments: [inner_arg, mutableArg, transferableArg, deletableArg],
});

return tx.build();
}
21 changes: 21 additions & 0 deletions bindings/wasm/iota_interaction_ts/lib/move_calls/asset/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { ObjectRef, Transaction } from "@iota/iota.js/transactions";

export function remove(
asset: ObjectRef,
asset_type: string,
packageId: string,
): Promise<Uint8Array> {
const tx = new Transaction();
const asset_arg = tx.objectRef(asset);

tx.moveCall({
target: `${packageId}::asset::delete`,
typeArguments: [asset_type],
arguments: [asset_arg],
});

return tx.build();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

export * from "./create";
export * from "./delete";
export * from "./transfer";
export * from "./update";
80 changes: 80 additions & 0 deletions bindings/wasm/iota_interaction_ts/lib/move_calls/asset/transfer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { SharedObjectRef } from "@iota/iota.js/dist/cjs/bcs/types";
import { ObjectRef, Transaction } from "@iota/iota.js/transactions";

export function transfer(
asset: ObjectRef,
assetType: string,
recipient: string,
packageId: string,
): Promise<Uint8Array> {
const tx = new Transaction();
const assetArg = tx.objectRef(asset);
const recipientArg = tx.pure.address(recipient);

tx.moveCall({
target: `${packageId}::asset::transfer`,
typeArguments: [assetType],
arguments: [assetArg, recipientArg],
});

return tx.build();
}

function makeTx(
proposal: SharedObjectRef,
cap: ObjectRef,
asset: ObjectRef,
assetType: string,
packageId: string,
functionName: string,
): Promise<Uint8Array> {
const tx = new Transaction();
const proposalArg = tx.sharedObjectRef(proposal);
const capArg = tx.objectRef(cap);
const assetArg = tx.objectRef(asset);

tx.moveCall({
target: `${packageId}::asset::${functionName}`,
typeArguments: [assetType],
arguments: [proposalArg, capArg, assetArg],
});

return tx.build();
}

export function acceptProposal(
proposal: SharedObjectRef,
recipientCap: ObjectRef,
asset: ObjectRef,
assetType: string,
packageId: string,
): Promise<Uint8Array> {
return makeTx(
proposal,
recipientCap,
asset,
assetType,
packageId,
"accept",
);
}

export function concludeOrCancel(
proposal: SharedObjectRef,
senderCap: ObjectRef,
asset: ObjectRef,
assetType: string,
packageId: string,
): Promise<Uint8Array> {
return makeTx(
proposal,
senderCap,
asset,
assetType,
packageId,
"conclude_or_cancel",
);
}
23 changes: 23 additions & 0 deletions bindings/wasm/iota_interaction_ts/lib/move_calls/asset/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { ObjectRef, Transaction } from "@iota/iota.js/transactions";

export function update(
asset: ObjectRef,
content: Uint8Array,
contentType: string,
packageId: string,
): Promise<Uint8Array> {
const tx = new Transaction();
const contentArg = tx.pure(content);
const assetArg = tx.objectRef(asset);

tx.moveCall({
target: `${packageId}::asset::update`,
typeArguments: [contentType],
arguments: [assetArg, contentArg],
});

return tx.build();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { SharedObjectRef } from "@iota/iota.js/dist/cjs/bcs/types";
import { IotaObjectData } from "@iota/iota.js/dist/cjs/client";
import { ObjectRef, Transaction, TransactionArgument } from "@iota/iota.js/transactions";
import { getControllerDelegation, putBackDelegationToken } from "../utils";

export function proposeBorrow(
identity: SharedObjectRef,
capability: ObjectRef,
objects: string[],
packageId: string,
expiration?: number,
): Promise<Uint8Array> {
const tx = new Transaction();
const cap = tx.objectRef(capability);
const [delegationToken, borrow] = getControllerDelegation(tx, cap, packageId);
const identityArg = tx.sharedObjectRef(identity);
const exp = tx.pure.option("u64", expiration);
const objectsArg = tx.pure.vector("id", objects);

tx.moveCall({
target: `${packageId}::identity::propose_borrow`,
arguments: [identityArg, delegationToken, exp, objectsArg],
});

putBackDelegationToken(tx, cap, delegationToken, borrow, packageId);

return tx.build();
}

export function executeBorrow(
identity: SharedObjectRef,
capability: ObjectRef,
proposalId: string,
objects: IotaObjectData[],
intentFn: (arg0: Transaction, arg1: Map<string, [TransactionArgument, IotaObjectData]>) => void,
packageId: string,
): Promise<Uint8Array> {
const tx = new Transaction();
const cap = tx.objectRef(capability);
const [delegationToken, borrow] = getControllerDelegation(tx, cap, packageId);
const proposal = tx.pure.id(proposalId);
const identityArg = tx.sharedObjectRef(identity);

let action = tx.moveCall({
target: `${packageId}::identity::execute_proposal`,
typeArguments: [`${packageId}::borrow_proposal::Borrow`],
arguments: [identityArg, delegationToken, proposal],
});

putBackDelegationToken(tx, cap, delegationToken, borrow, packageId);

const objectArgMap = new Map<string, [TransactionArgument, IotaObjectData]>();
for (const obj of objects) {
const recvObj = tx.receivingRef(obj);
const objArg = tx.moveCall({
target: `${packageId}::identity::execute_borrow`,
typeArguments: [obj.type!],
arguments: [identityArg, action, recvObj],
});

objectArgMap.set(obj.objectId, [objArg, obj]);
}

intentFn(tx, objectArgMap);

for (const [obj, objData] of objectArgMap.values()) {
tx.moveCall({
target: `${packageId}::borrow_proposal::put_back`,
typeArguments: [objData.type!],
arguments: [action, obj],
});
}

tx.moveCall({
target: `${packageId}::transfer_proposal::conclude_borrow`,
arguments: [action],
});

return tx.build();
}

export function createAndExecuteBorrow(
identity: SharedObjectRef,
capability: ObjectRef,
objects: IotaObjectData[],
intentFn: (arg0: Transaction, arg1: Map<string, [TransactionArgument, IotaObjectData]>) => void,
packageId: string,
expiration?: number,
): Promise<Uint8Array> {
const tx = new Transaction();
const cap = tx.objectRef(capability);
const [delegationToken, borrow] = getControllerDelegation(tx, cap, packageId);
const identityArg = tx.sharedObjectRef(identity);
const exp = tx.pure.option("u64", expiration);
const objectsArg = tx.pure.vector("id", objects.map(obj => obj.objectId));

const proposal = tx.moveCall({
target: `${packageId}::identity::propose_borrow`,
arguments: [identityArg, delegationToken, exp, objectsArg],
});

let action = tx.moveCall({
target: `${packageId}::identity::execute_proposal`,
typeArguments: [`${packageId}::borrow_proposal::Borrow`],
arguments: [identityArg, delegationToken, proposal],
});

putBackDelegationToken(tx, cap, delegationToken, borrow, packageId);

const objectArgMap = new Map<string, [TransactionArgument, IotaObjectData]>();
for (const obj of objects) {
const recvObj = tx.receivingRef(obj);
const objArg = tx.moveCall({
target: `${packageId}::identity::execute_borrow`,
typeArguments: [obj.type!],
arguments: [identityArg, action, recvObj],
});

objectArgMap.set(obj.objectId, [objArg, obj]);
}

intentFn(tx, objectArgMap);

for (const [obj, objData] of objectArgMap.values()) {
tx.moveCall({
target: `${packageId}::borrow_proposal::put_back`,
typeArguments: [objData.type!],
arguments: [action, obj],
});
}

tx.moveCall({
target: `${packageId}::transfer_proposal::conclude_borrow`,
arguments: [action],
});
return tx.build();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { SharedObjectRef } from "@iota/iota.js/dist/cjs/bcs/types";
import { ObjectRef, Transaction } from "@iota/iota.js/transactions";
import { getControllerDelegation, putBackDelegationToken } from "../utils";

export function proposeConfigChange(
identity: SharedObjectRef,
controllerCap: ObjectRef,
controllersToAdd: [string, number][],
controllersToRemove: string[],
controllersToUpdate: [string, number][],
packageId: string,
expiration?: number,
threshold?: number,
): Promise<Uint8Array> {
const tx = new Transaction();
const addressesToAdd = tx.pure.vector("address", controllersToAdd.map(c => c[0]));
const vpsToAdd = tx.pure.vector("u64", controllersToAdd.map(c => c[1]));
const controllersToAddArg = tx.moveCall({
target: `${packageId}::utils::vec_map_from_keys_values`,
typeArguments: ["address", "u64"],
arguments: [addressesToAdd, vpsToAdd],
});

const idsToUpdate = tx.pure.vector("id", controllersToUpdate.map(c => c[0]));
const vpsToUpdate = tx.pure.vector("u64", controllersToUpdate.map(c => c[1]));
const controllersToUpdateArg = tx.moveCall({
target: `${packageId}::utils::vec_map_from_keys_values`,
typeArguments: ["id", "u64"],
arguments: [idsToUpdate, vpsToUpdate],
});

const identityArg = tx.sharedObjectRef(identity);
const cap = tx.objectRef(controllerCap);
const [delegationToken, borrow] = getControllerDelegation(tx, cap, packageId);
const thresholdArg = tx.pure.option("u64", threshold);
const exp = tx.pure.option("u64", expiration);
const controllersToRemoveArg = tx.pure.vector("id", controllersToRemove);

tx.moveCall({
target: `${packageId}::identity::propose_config_change`,
arguments: [identityArg, delegationToken, exp, thresholdArg, controllersToAddArg, controllersToRemoveArg,
controllersToUpdateArg],
});

putBackDelegationToken(tx, cap, delegationToken, borrow, packageId);

return tx.build();
}

export function executeConfigChange(
identity: SharedObjectRef,
capability: ObjectRef,
proposalId: string,
packageId: string,
): Promise<Uint8Array> {
const tx = new Transaction();
const cap = tx.objectRef(capability);
const [delegationToken, borrow] = getControllerDelegation(tx, cap, packageId);
const proposal = tx.pure.id(proposalId);
const identityArg = tx.sharedObjectRef(identity);

tx.moveCall({
target: `${packageId}::identity::execute_config_change`,
arguments: [identityArg, delegationToken, proposal],
});

putBackDelegationToken(tx, cap, delegationToken, borrow, packageId);

return tx.build();
}
Loading

0 comments on commit c3d5f09

Please sign in to comment.