Skip to content

Commit 5c92c4b

Browse files
committed
add coin lookup to getCoinForTransaction (ts impl)
- now checks balances and pages through coins instead of only taking the second coin - align error messages between Rust and TypeScript
1 parent fd985de commit 5c92c4b

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

bindings/wasm/iota_interaction_ts/lib/iota_client_helpers.ts

+31-8
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ import {
99
OwnedObjectRef,
1010
Signature,
1111
} from "@iota/iota-sdk/client";
12-
import { messageWithIntent, PublicKey, toSerializedSignature } from "@iota/iota-sdk/cryptography";
13-
import { Ed25519PublicKey } from "@iota/iota-sdk/keypairs/ed25519";
1412
import { GasData, TransactionDataBuilder } from "@iota/iota-sdk/transactions";
15-
import { blake2b } from "@noble/hashes/blake2b";
1613

1714
export type Signer = { sign(data: Uint8Array): Promise<Signature> };
1815

16+
const MINIMUM_BALANCE_FOR_COIN = BigInt(1_000_000_000);
17+
1918
export class WasmIotaTransactionBlockResponseWrapper {
2019
response: IotaTransactionBlockResponse;
2120

@@ -54,13 +53,37 @@ export class WasmIotaTransactionBlockResponseWrapper {
5453
}
5554
}
5655

57-
async function getCoinForTransaction(iotaClient: IotaClient, senderAddress: string): Promise<CoinStruct> {
58-
const coins = await iotaClient.getCoins({ owner: senderAddress });
59-
if (coins.data.length === 0) {
60-
throw new Error(`could not find coins for transaction with sender ${senderAddress}`);
56+
function byHighestBalance<T extends { balance: BigInt }>({ balance: a }: T, { balance: b }: T) {
57+
if (a > b) {
58+
return -1;
59+
}
60+
if (a < b) {
61+
return 1;
6162
}
63+
return 0;
64+
}
65+
66+
async function getCoinForTransaction(iotaClient: IotaClient, senderAddress: string): Promise<CoinStruct> {
67+
let cursor: string | null | undefined = undefined;
68+
do {
69+
const response = await iotaClient.getCoins({ owner: senderAddress, cursor });
70+
if (response.data.length === 0) {
71+
throw new Error(`no coin found with minimum required balance of ${MINIMUM_BALANCE_FOR_COIN} for address ${senderAddress}"`);
72+
}
73+
74+
let sortedValidCoins = response.data
75+
.map((coin) => ({ coin, balance: BigInt(coin.balance) }))
76+
.filter(({ balance }) => balance >= MINIMUM_BALANCE_FOR_COIN)
77+
.sort(byHighestBalance);
78+
79+
if (sortedValidCoins.length >= 1) {
80+
return sortedValidCoins[0].coin;
81+
}
82+
83+
cursor = response.nextCursor;
84+
} while (cursor)
6285

63-
return coins.data[1];
86+
throw new Error(`no coin found with minimum required balance of ${MINIMUM_BALANCE_FOR_COIN} for address ${senderAddress}"`);
6487
}
6588

6689
/**

identity_iota_core/src/iota_interaction_rust/iota_client_rust_sdk.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,8 @@ impl IotaClientRustSdk {
570570

571571
let Some(coin) = coins.data.into_iter().max_by_key(|coin| coin.balance) else {
572572
return Err(Error::GasIssue(format!(
573-
"no coins found for address {}",
574-
sender_address
573+
"no coin found with minimum required balance of {} for address {}",
574+
MINIMUM_BALANCE, sender_address
575575
)));
576576
};
577577

0 commit comments

Comments
 (0)