@owney/sdk 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -241,6 +241,7 @@ function mapHistory(raw, chainId) {
241
241
  const actionMap = {
242
242
  "Deposit to protocol": "Deposit",
243
243
  "Top up wallet": "Top up",
244
+ "Partial withdraw from protocol": "Withdraw",
244
245
  "Withdraw from protocol": "Withdraw",
245
246
  Rebalance: "Rebalance"
246
247
  };
@@ -947,18 +948,27 @@ var OwneySDK = class {
947
948
  }
948
949
  const agent = this.getAgent(agentId);
949
950
  this.validateAssetSupport(agent, chainId, asset);
950
- this.validateMinDepositAmount(agent, chainId, asset, amount);
951
+ await this.validateMinDepositAmount(agent, state, chainId, asset, amount);
951
952
  return agent.deposit(state, chainId, amount, depositCallback);
952
953
  }
953
954
  const totalAmount = BigInt(amount);
954
955
  const eligibleAgents = this.getEligibleAgents(chainId, asset, {
955
956
  excludeDisabled: true
956
957
  });
958
+ const exemptFlags = await Promise.all(
959
+ eligibleAgents.map(
960
+ (a) => this.hasExistingBalance(a, state, chainId, asset)
961
+ )
962
+ );
963
+ const exempt = new Set(
964
+ eligibleAgents.filter((_, i) => exemptFlags[i]).map((a) => a.id)
965
+ );
957
966
  const agentAmounts = this.splitDepositAmount(
958
967
  totalAmount,
959
968
  eligibleAgents,
960
969
  chainId,
961
- asset
970
+ asset,
971
+ exempt
962
972
  );
963
973
  if (agentAmounts.length === 0) {
964
974
  throw new OwneyError(
@@ -985,7 +995,7 @@ var OwneySDK = class {
985
995
  const assetEntry = chainAssets?.assets.find((a) => a.symbol === asset);
986
996
  return BigInt(assetEntry?.minDepositAmount ?? "0");
987
997
  }
988
- splitDepositAmount(totalAmount, agents, chainId, asset) {
998
+ splitDepositAmount(totalAmount, agents, chainId, asset, exempt = /* @__PURE__ */ new Set()) {
989
999
  if (agents.length === 0)
990
1000
  return [];
991
1001
  const perAgent = totalAmount / BigInt(agents.length);
@@ -995,7 +1005,7 @@ var OwneySDK = class {
995
1005
  amount: i === agents.length - 1 ? perAgent + remainder : perAgent
996
1006
  }));
997
1007
  const valid = splits.filter(
998
- (s) => s.amount >= this.getMinDepositAmount(s.agent, chainId, asset)
1008
+ (s) => exempt.has(s.agent.id) || s.amount >= this.getMinDepositAmount(s.agent, chainId, asset)
999
1009
  );
1000
1010
  if (valid.length === agents.length) {
1001
1011
  return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
@@ -1004,24 +1014,45 @@ var OwneySDK = class {
1004
1014
  totalAmount,
1005
1015
  valid.map((s) => s.agent),
1006
1016
  chainId,
1007
- asset
1017
+ asset,
1018
+ exempt
1008
1019
  );
1009
1020
  }
1010
- validateMinDepositAmount(agent, chainId, asset, amount) {
1021
+ async validateMinDepositAmount(agent, state, chainId, asset, amount) {
1011
1022
  const minDepositAmount = this.getMinDepositAmount(agent, chainId, asset);
1012
1023
  const parsedAmount = BigInt(amount);
1013
- if (parsedAmount < minDepositAmount) {
1014
- throw new OwneyError(
1015
- "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1016
- `Amount "${amount}" is below the required minimum deposit "${minDepositAmount.toString()}" for agent "${agent.id}" on chain ${chainId} for asset "${asset}".`,
1017
- {
1018
- agentId: agent.id,
1019
- chainId,
1020
- asset,
1021
- amount,
1022
- minDepositAmount: minDepositAmount.toString()
1023
- }
1024
+ if (parsedAmount >= minDepositAmount)
1025
+ return;
1026
+ if (await this.hasExistingBalance(agent, state, chainId, asset))
1027
+ return;
1028
+ throw new OwneyError(
1029
+ "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1030
+ `Amount "${amount}" is below the required minimum deposit "${minDepositAmount.toString()}" for agent "${agent.id}" on chain ${chainId} for asset "${asset}".`,
1031
+ {
1032
+ agentId: agent.id,
1033
+ chainId,
1034
+ asset,
1035
+ amount,
1036
+ minDepositAmount: minDepositAmount.toString()
1037
+ }
1038
+ );
1039
+ }
1040
+ /**
1041
+ * Whether the user already holds a non-zero balance with `agent` for the
1042
+ * given `(chainId, asset)`. Used to exempt top-up deposits from the
1043
+ * per-agent minimum. Fails closed: any error reading balances returns
1044
+ * false, so the minimum is enforced as today.
1045
+ */
1046
+ async hasExistingBalance(agent, state, chainId, asset) {
1047
+ try {
1048
+ const balance = await agent.getBalances(state, chainId);
1049
+ const target = asset.toLowerCase();
1050
+ const token = balance.tokens.find(
1051
+ (t) => t.chainId === chainId && t.asset.toLowerCase() === target
1024
1052
  );
1053
+ return !!token && BigInt(token.amount) > 0n;
1054
+ } catch {
1055
+ return false;
1025
1056
  }
1026
1057
  }
1027
1058
  validateAssetSupport(agent, chainId, asset) {
@@ -1104,7 +1135,10 @@ var OwneySDK = class {
1104
1135
  { asset, agentErrors: agentErrors2 }
1105
1136
  );
1106
1137
  }
1107
- return { agentResult: results2 };
1138
+ return {
1139
+ agentResult: results2,
1140
+ totalWithdrawn: sumWithdrawnAmount(results2).toString()
1141
+ };
1108
1142
  }
1109
1143
  const requested = BigInt(amount);
1110
1144
  const aggregated = await this.getBalances();
@@ -1193,7 +1227,7 @@ var OwneySDK = class {
1193
1227
  }
1194
1228
  );
1195
1229
  }
1196
- return { agentResult: results };
1230
+ return { agentResult: results, totalWithdrawn: withdrawn.toString() };
1197
1231
  }
1198
1232
  // --- Portfolio reads ---
1199
1233
  /**
package/dist/index.d.cts CHANGED
@@ -114,6 +114,7 @@ interface AgentWithdrawResult {
114
114
  }
115
115
  interface OwneyWithdrawResult {
116
116
  agentResult: Record<AgentId, AgentWithdrawResult>;
117
+ totalWithdrawn: string;
117
118
  }
118
119
  interface OwneyToken {
119
120
  chain: OwneySupportedChains;
@@ -277,6 +278,13 @@ declare class OwneySDK {
277
278
  private getMinDepositAmount;
278
279
  private splitDepositAmount;
279
280
  private validateMinDepositAmount;
281
+ /**
282
+ * Whether the user already holds a non-zero balance with `agent` for the
283
+ * given `(chainId, asset)`. Used to exempt top-up deposits from the
284
+ * per-agent minimum. Fails closed: any error reading balances returns
285
+ * false, so the minimum is enforced as today.
286
+ */
287
+ private hasExistingBalance;
280
288
  private validateAssetSupport;
281
289
  private getEligibleAgents;
282
290
  /**
package/dist/index.d.ts CHANGED
@@ -114,6 +114,7 @@ interface AgentWithdrawResult {
114
114
  }
115
115
  interface OwneyWithdrawResult {
116
116
  agentResult: Record<AgentId, AgentWithdrawResult>;
117
+ totalWithdrawn: string;
117
118
  }
118
119
  interface OwneyToken {
119
120
  chain: OwneySupportedChains;
@@ -277,6 +278,13 @@ declare class OwneySDK {
277
278
  private getMinDepositAmount;
278
279
  private splitDepositAmount;
279
280
  private validateMinDepositAmount;
281
+ /**
282
+ * Whether the user already holds a non-zero balance with `agent` for the
283
+ * given `(chainId, asset)`. Used to exempt top-up deposits from the
284
+ * per-agent minimum. Fails closed: any error reading balances returns
285
+ * false, so the minimum is enforced as today.
286
+ */
287
+ private hasExistingBalance;
280
288
  private validateAssetSupport;
281
289
  private getEligibleAgents;
282
290
  /**
package/dist/index.js CHANGED
@@ -211,6 +211,7 @@ function mapHistory(raw, chainId) {
211
211
  const actionMap = {
212
212
  "Deposit to protocol": "Deposit",
213
213
  "Top up wallet": "Top up",
214
+ "Partial withdraw from protocol": "Withdraw",
214
215
  "Withdraw from protocol": "Withdraw",
215
216
  Rebalance: "Rebalance"
216
217
  };
@@ -917,18 +918,27 @@ var OwneySDK = class {
917
918
  }
918
919
  const agent = this.getAgent(agentId);
919
920
  this.validateAssetSupport(agent, chainId, asset);
920
- this.validateMinDepositAmount(agent, chainId, asset, amount);
921
+ await this.validateMinDepositAmount(agent, state, chainId, asset, amount);
921
922
  return agent.deposit(state, chainId, amount, depositCallback);
922
923
  }
923
924
  const totalAmount = BigInt(amount);
924
925
  const eligibleAgents = this.getEligibleAgents(chainId, asset, {
925
926
  excludeDisabled: true
926
927
  });
928
+ const exemptFlags = await Promise.all(
929
+ eligibleAgents.map(
930
+ (a) => this.hasExistingBalance(a, state, chainId, asset)
931
+ )
932
+ );
933
+ const exempt = new Set(
934
+ eligibleAgents.filter((_, i) => exemptFlags[i]).map((a) => a.id)
935
+ );
927
936
  const agentAmounts = this.splitDepositAmount(
928
937
  totalAmount,
929
938
  eligibleAgents,
930
939
  chainId,
931
- asset
940
+ asset,
941
+ exempt
932
942
  );
933
943
  if (agentAmounts.length === 0) {
934
944
  throw new OwneyError(
@@ -955,7 +965,7 @@ var OwneySDK = class {
955
965
  const assetEntry = chainAssets?.assets.find((a) => a.symbol === asset);
956
966
  return BigInt(assetEntry?.minDepositAmount ?? "0");
957
967
  }
958
- splitDepositAmount(totalAmount, agents, chainId, asset) {
968
+ splitDepositAmount(totalAmount, agents, chainId, asset, exempt = /* @__PURE__ */ new Set()) {
959
969
  if (agents.length === 0)
960
970
  return [];
961
971
  const perAgent = totalAmount / BigInt(agents.length);
@@ -965,7 +975,7 @@ var OwneySDK = class {
965
975
  amount: i === agents.length - 1 ? perAgent + remainder : perAgent
966
976
  }));
967
977
  const valid = splits.filter(
968
- (s) => s.amount >= this.getMinDepositAmount(s.agent, chainId, asset)
978
+ (s) => exempt.has(s.agent.id) || s.amount >= this.getMinDepositAmount(s.agent, chainId, asset)
969
979
  );
970
980
  if (valid.length === agents.length) {
971
981
  return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
@@ -974,24 +984,45 @@ var OwneySDK = class {
974
984
  totalAmount,
975
985
  valid.map((s) => s.agent),
976
986
  chainId,
977
- asset
987
+ asset,
988
+ exempt
978
989
  );
979
990
  }
980
- validateMinDepositAmount(agent, chainId, asset, amount) {
991
+ async validateMinDepositAmount(agent, state, chainId, asset, amount) {
981
992
  const minDepositAmount = this.getMinDepositAmount(agent, chainId, asset);
982
993
  const parsedAmount = BigInt(amount);
983
- if (parsedAmount < minDepositAmount) {
984
- throw new OwneyError(
985
- "DEPOSIT_AMOUNT_BELOW_MINIMUM",
986
- `Amount "${amount}" is below the required minimum deposit "${minDepositAmount.toString()}" for agent "${agent.id}" on chain ${chainId} for asset "${asset}".`,
987
- {
988
- agentId: agent.id,
989
- chainId,
990
- asset,
991
- amount,
992
- minDepositAmount: minDepositAmount.toString()
993
- }
994
+ if (parsedAmount >= minDepositAmount)
995
+ return;
996
+ if (await this.hasExistingBalance(agent, state, chainId, asset))
997
+ return;
998
+ throw new OwneyError(
999
+ "DEPOSIT_AMOUNT_BELOW_MINIMUM",
1000
+ `Amount "${amount}" is below the required minimum deposit "${minDepositAmount.toString()}" for agent "${agent.id}" on chain ${chainId} for asset "${asset}".`,
1001
+ {
1002
+ agentId: agent.id,
1003
+ chainId,
1004
+ asset,
1005
+ amount,
1006
+ minDepositAmount: minDepositAmount.toString()
1007
+ }
1008
+ );
1009
+ }
1010
+ /**
1011
+ * Whether the user already holds a non-zero balance with `agent` for the
1012
+ * given `(chainId, asset)`. Used to exempt top-up deposits from the
1013
+ * per-agent minimum. Fails closed: any error reading balances returns
1014
+ * false, so the minimum is enforced as today.
1015
+ */
1016
+ async hasExistingBalance(agent, state, chainId, asset) {
1017
+ try {
1018
+ const balance = await agent.getBalances(state, chainId);
1019
+ const target = asset.toLowerCase();
1020
+ const token = balance.tokens.find(
1021
+ (t) => t.chainId === chainId && t.asset.toLowerCase() === target
994
1022
  );
1023
+ return !!token && BigInt(token.amount) > 0n;
1024
+ } catch {
1025
+ return false;
995
1026
  }
996
1027
  }
997
1028
  validateAssetSupport(agent, chainId, asset) {
@@ -1074,7 +1105,10 @@ var OwneySDK = class {
1074
1105
  { asset, agentErrors: agentErrors2 }
1075
1106
  );
1076
1107
  }
1077
- return { agentResult: results2 };
1108
+ return {
1109
+ agentResult: results2,
1110
+ totalWithdrawn: sumWithdrawnAmount(results2).toString()
1111
+ };
1078
1112
  }
1079
1113
  const requested = BigInt(amount);
1080
1114
  const aggregated = await this.getBalances();
@@ -1163,7 +1197,7 @@ var OwneySDK = class {
1163
1197
  }
1164
1198
  );
1165
1199
  }
1166
- return { agentResult: results };
1200
+ return { agentResult: results, totalWithdrawn: withdrawn.toString() };
1167
1201
  }
1168
1202
  // --- Portfolio reads ---
1169
1203
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",