@aboutcircles/sdk 0.1.0
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/README.md +249 -0
- package/dist/Sdk.d.ts +282 -0
- package/dist/Sdk.d.ts.map +1 -0
- package/dist/Sdk.js +501 -0
- package/dist/avatars/BaseGroupAvatar.d.ts +97 -0
- package/dist/avatars/BaseGroupAvatar.d.ts.map +1 -0
- package/dist/avatars/BaseGroupAvatar.js +221 -0
- package/dist/avatars/CommonAvatar.d.ts +402 -0
- package/dist/avatars/CommonAvatar.d.ts.map +1 -0
- package/dist/avatars/CommonAvatar.js +644 -0
- package/dist/avatars/HumanAvatar.d.ts +412 -0
- package/dist/avatars/HumanAvatar.d.ts.map +1 -0
- package/dist/avatars/HumanAvatar.js +610 -0
- package/dist/avatars/OrganisationAvatar.d.ts +187 -0
- package/dist/avatars/OrganisationAvatar.d.ts.map +1 -0
- package/dist/avatars/OrganisationAvatar.js +310 -0
- package/dist/avatars/index.d.ts +9 -0
- package/dist/avatars/index.d.ts.map +1 -0
- package/dist/avatars/index.js +7 -0
- package/dist/ccip-dw9vbgp0.js +4533 -0
- package/dist/errors.d.ts +64 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +131 -0
- package/dist/index-3hqyeswk.js +25 -0
- package/dist/index-pps0tkk3.js +356 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15308 -0
- package/dist/native-45v6vh69.js +20 -0
- package/dist/secp256k1-mjj44cj6.js +2115 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { Address, AvatarRow, ContractRunner, TokenBalanceRow } from '@aboutcircles/sdk-types';
|
|
2
|
+
import type { TransactionReceipt } from 'viem';
|
|
3
|
+
import type { Core } from '@aboutcircles/sdk-core';
|
|
4
|
+
import { CommonAvatar, type PathfindingOptions } from './CommonAvatar';
|
|
5
|
+
/**
|
|
6
|
+
* OrganisationAvatar class implementation
|
|
7
|
+
* Provides a simplified, user-friendly wrapper around Circles protocol for organisation avatars
|
|
8
|
+
*
|
|
9
|
+
* This class represents an organisation avatar in the Circles ecosystem.
|
|
10
|
+
* Unlike human avatars, organisations cannot mint personal CRC tokens and do not require invitations.
|
|
11
|
+
* They can manage trust relationships, make transfers, and interact with group tokens.
|
|
12
|
+
*/
|
|
13
|
+
export declare class OrganisationAvatar extends CommonAvatar {
|
|
14
|
+
constructor(address: Address, core: Core, contractRunner?: ContractRunner, avatarInfo?: AvatarRow);
|
|
15
|
+
readonly balances: {
|
|
16
|
+
getTotal: () => Promise<bigint>;
|
|
17
|
+
getTokenBalances: () => Promise<TokenBalanceRow[]>;
|
|
18
|
+
getTotalSupply: () => Promise<bigint>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the maximum amount that can be replenished (converted to unwrapped personal CRC)
|
|
21
|
+
* This calculates how much of your wrapped tokens and other tokens can be converted
|
|
22
|
+
* into your own unwrapped ERC1155 personal CRC tokens using pathfinding
|
|
23
|
+
*
|
|
24
|
+
* @param options Optional pathfinding options
|
|
25
|
+
* @returns Maximum replenishable amount in atto-circles
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const maxReplenishable = await avatar.balances.getMaxReplenishable();
|
|
30
|
+
* console.log('Can replenish:', CirclesConverter.attoCirclesToCircles(maxReplenishable), 'CRC');
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
getMaxReplenishable: (options?: PathfindingOptions) => Promise<bigint>;
|
|
34
|
+
/**
|
|
35
|
+
* Replenish unwrapped personal CRC tokens by converting wrapped/other tokens
|
|
36
|
+
*
|
|
37
|
+
* This method uses pathfinding to find the best way to convert your available tokens
|
|
38
|
+
* (including wrapped tokens) into unwrapped ERC1155 personal CRC tokens.
|
|
39
|
+
*
|
|
40
|
+
* Useful when you have wrapped tokens or other people's tokens and want to
|
|
41
|
+
* convert them to your own personal unwrapped tokens for transfers.
|
|
42
|
+
*
|
|
43
|
+
* @param options Optional pathfinding options
|
|
44
|
+
* @returns Transaction receipt
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* // Convert all available wrapped/other tokens to unwrapped personal CRC
|
|
49
|
+
* const receipt = await avatar.balances.replenish();
|
|
50
|
+
* console.log('Replenished personal tokens, tx hash:', receipt.hash);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
replenish: (options?: PathfindingOptions) => Promise<TransactionReceipt>;
|
|
54
|
+
};
|
|
55
|
+
readonly groupToken: {
|
|
56
|
+
/**
|
|
57
|
+
* Mint group tokens by transferring collateral to the group's mint handler
|
|
58
|
+
* Uses pathfinding to transfer tokens along the trust network, including wrapped tokens
|
|
59
|
+
*
|
|
60
|
+
* @param group The group address to mint tokens from
|
|
61
|
+
* @param amount Amount of tokens to transfer to the mint handler (in atto-circles)
|
|
62
|
+
* @returns Transaction receipt
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* // Mint group tokens by sending 100 CRC to the group's mint handler
|
|
67
|
+
* const receipt = await avatar.groupToken.mint('0xGroupAddress...', BigInt(100e18));
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
mint: (group: Address, amount: bigint) => Promise<TransactionReceipt>;
|
|
71
|
+
/**
|
|
72
|
+
* Get the maximum amount that can be minted for a group
|
|
73
|
+
* This calculates the maximum transferable amount to the group's mint handler
|
|
74
|
+
* including wrapped token balances
|
|
75
|
+
*
|
|
76
|
+
* @param group The group address
|
|
77
|
+
* @returns Maximum mintable amount in atto-circles
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const maxMintable = await avatar.groupToken.getMaxMintableAmount('0xGroupAddress...');
|
|
82
|
+
* console.log('Can mint up to:', maxMintable.toString(), 'atto-circles');
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
getMaxMintableAmount: (group: Address) => Promise<bigint>;
|
|
86
|
+
/**
|
|
87
|
+
* Automatically redeem collateral tokens from a Base Group's treasury
|
|
88
|
+
*
|
|
89
|
+
* Performs automatic redemption by determining trusted collaterals and using pathfinder for optimal flow.
|
|
90
|
+
* Only supports Base Group types. The function uses pathfinder to determine the optimal redemption path
|
|
91
|
+
* and validates that sufficient liquidity exists before attempting redemption.
|
|
92
|
+
*
|
|
93
|
+
* Note: Organizations don't have personal tokens. This method uses the tokens held by the organization
|
|
94
|
+
* (which are other avatars' tokens or other group tokens) to redeem from the specified group.
|
|
95
|
+
*
|
|
96
|
+
* @param group The address of the Base Group from which to redeem collateral tokens
|
|
97
|
+
* @param amount The amount of group tokens to redeem for collateral (must be > 0 and <= max redeemable)
|
|
98
|
+
* @returns A Promise resolving to the transaction receipt upon successful automatic redemption
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* // Redeem 100 group tokens for collateral
|
|
103
|
+
* const receipt = await orgAvatar.groupToken.redeem('0xGroupAddress...', BigInt(100e18));
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
redeem: (group: Address, amount: bigint) => Promise<TransactionReceipt>;
|
|
107
|
+
properties: {
|
|
108
|
+
/**
|
|
109
|
+
* Get the owner of a specific group
|
|
110
|
+
* @param group The group address
|
|
111
|
+
* @returns The owner address of the group
|
|
112
|
+
*/
|
|
113
|
+
owner: (group: Address) => Promise<Address>;
|
|
114
|
+
/**
|
|
115
|
+
* Get the mint handler address of a specific group
|
|
116
|
+
* @param group The group address
|
|
117
|
+
* @returns The mint handler address
|
|
118
|
+
*/
|
|
119
|
+
mintHandler: (group: Address) => Promise<Address>;
|
|
120
|
+
/**
|
|
121
|
+
* Get the treasury (redemption handler) address of a specific group
|
|
122
|
+
* @param group The group address
|
|
123
|
+
* @returns The treasury address where redemptions are handled
|
|
124
|
+
*/
|
|
125
|
+
treasury: (group: Address) => Promise<Address>;
|
|
126
|
+
/**
|
|
127
|
+
* Get the service address of a specific group
|
|
128
|
+
* @param group The group address
|
|
129
|
+
* @returns The service address
|
|
130
|
+
*/
|
|
131
|
+
service: (group: Address) => Promise<Address>;
|
|
132
|
+
/**
|
|
133
|
+
* Get the fee collection address of a specific group
|
|
134
|
+
* @param group The group address
|
|
135
|
+
* @returns The fee collection address
|
|
136
|
+
*/
|
|
137
|
+
feeCollection: (group: Address) => Promise<Address>;
|
|
138
|
+
/**
|
|
139
|
+
* Get all membership conditions for a specific group
|
|
140
|
+
* @param group The group address
|
|
141
|
+
* @returns Array of membership condition addresses
|
|
142
|
+
*/
|
|
143
|
+
getMembershipConditions: (group: Address) => Promise<Address[]>;
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
readonly group: {
|
|
147
|
+
properties: {
|
|
148
|
+
/**
|
|
149
|
+
* Get the owner of a specific group
|
|
150
|
+
* @param group The group address
|
|
151
|
+
* @returns The owner address of the group
|
|
152
|
+
*/
|
|
153
|
+
owner: (group: Address) => Promise<Address>;
|
|
154
|
+
/**
|
|
155
|
+
* Get the mint handler address of a specific group
|
|
156
|
+
* @param group The group address
|
|
157
|
+
* @returns The mint handler address
|
|
158
|
+
*/
|
|
159
|
+
mintHandler: (group: Address) => Promise<Address>;
|
|
160
|
+
/**
|
|
161
|
+
* Get the treasury (redemption handler) address of a specific group
|
|
162
|
+
* @param group The group address
|
|
163
|
+
* @returns The treasury address where redemptions are handled
|
|
164
|
+
*/
|
|
165
|
+
treasury: (group: Address) => Promise<Address>;
|
|
166
|
+
/**
|
|
167
|
+
* Get the service address of a specific group
|
|
168
|
+
* @param group The group address
|
|
169
|
+
* @returns The service address
|
|
170
|
+
*/
|
|
171
|
+
service: (group: Address) => Promise<Address>;
|
|
172
|
+
/**
|
|
173
|
+
* Get the fee collection address of a specific group
|
|
174
|
+
* @param group The group address
|
|
175
|
+
* @returns The fee collection address
|
|
176
|
+
*/
|
|
177
|
+
feeCollection: (group: Address) => Promise<Address>;
|
|
178
|
+
/**
|
|
179
|
+
* Get all membership conditions for a specific group
|
|
180
|
+
* @param group The group address
|
|
181
|
+
* @returns Array of membership condition addresses
|
|
182
|
+
*/
|
|
183
|
+
getMembershipConditions: (group: Address) => Promise<Address[]>;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=OrganisationAvatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrganisationAvatar.d.ts","sourceRoot":"","sources":["../../src/avatars/OrganisationAvatar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,cAAc,EACd,eAAe,EAEhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAInD,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEvE;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;gBAEhD,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,cAAc,CAAC,EAAE,cAAc,EAC/B,UAAU,CAAC,EAAE,SAAS;IASxB,SAAgB,QAAQ;wBACF,OAAO,CAAC,MAAM,CAAC;gCAIP,OAAO,CAAC,eAAe,EAAE,CAAC;8BAI5B,OAAO,CAAC,MAAM,CAAC;QAIzC;;;;;;;;;;;;;WAaG;wCACmC,kBAAkB,KAAG,OAAO,CAAC,MAAM,CAAC;QAgB1E;;;;;;;;;;;;;;;;;;WAkBG;8BACyB,kBAAkB,KAAG,OAAO,CAAC,kBAAkB,CAAC;MAkB5E;IAUF,SAAgB,UAAU;QACxB;;;;;;;;;;;;;WAaG;sBAEM,OAAO,UACN,MAAM,KACb,OAAO,CAAC,kBAAkB,CAAC;QAqB9B;;;;;;;;;;;;;WAaG;sCACiC,OAAO,KAAG,OAAO,CAAC,MAAM,CAAC;QAiB7D;;;;;;;;;;;;;;;;;;;WAmBG;wBAEM,OAAO,UACN,MAAM,KACb,OAAO,CAAC,kBAAkB,CAAC;;YAyF5B;;;;eAIG;2BACkB,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQ/C;;;;eAIG;iCACwB,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQrD;;;;eAIG;8BACqB,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQlD;;;;eAIG;6BACoB,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQjD;;;;eAIG;mCAC0B,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQvD;;;;eAIG;6CACoC,OAAO,KAAG,OAAO,CAAC,OAAO,EAAE,CAAC;;MASrE;IAGF,SAAgB,KAAK;;YAlFjB;;;;eAIG;2BACkB,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQ/C;;;;eAIG;iCACwB,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQrD;;;;eAIG;8BACqB,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQlD;;;;eAIG;6BACoB,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQjD;;;;eAIG;mCAC0B,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC;YAQvD;;;;eAIG;6CACoC,OAAO,KAAG,OAAO,CAAC,OAAO,EAAE,CAAC;;MAcrE;CASH"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { ValidationError } from '@aboutcircles/sdk-utils';
|
|
2
|
+
import { SdkError } from '../errors';
|
|
3
|
+
import { BaseGroupContract } from '@aboutcircles/sdk-core';
|
|
4
|
+
import { CommonAvatar } from './CommonAvatar';
|
|
5
|
+
/**
|
|
6
|
+
* OrganisationAvatar class implementation
|
|
7
|
+
* Provides a simplified, user-friendly wrapper around Circles protocol for organisation avatars
|
|
8
|
+
*
|
|
9
|
+
* This class represents an organisation avatar in the Circles ecosystem.
|
|
10
|
+
* Unlike human avatars, organisations cannot mint personal CRC tokens and do not require invitations.
|
|
11
|
+
* They can manage trust relationships, make transfers, and interact with group tokens.
|
|
12
|
+
*/
|
|
13
|
+
export class OrganisationAvatar extends CommonAvatar {
|
|
14
|
+
constructor(address, core, contractRunner, avatarInfo) {
|
|
15
|
+
super(address, core, contractRunner, avatarInfo);
|
|
16
|
+
}
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Override Balance Methods with Organisation-Specific Features
|
|
19
|
+
// ============================================================================
|
|
20
|
+
balances = {
|
|
21
|
+
getTotal: async () => {
|
|
22
|
+
return await this.rpc.balance.getTotalBalance(this.address);
|
|
23
|
+
},
|
|
24
|
+
getTokenBalances: async () => {
|
|
25
|
+
return await this.rpc.balance.getTokenBalances(this.address);
|
|
26
|
+
},
|
|
27
|
+
getTotalSupply: async () => {
|
|
28
|
+
throw SdkError.unsupportedOperation('getTotalSupply', 'This method is not yet implemented');
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Get the maximum amount that can be replenished (converted to unwrapped personal CRC)
|
|
32
|
+
* This calculates how much of your wrapped tokens and other tokens can be converted
|
|
33
|
+
* into your own unwrapped ERC1155 personal CRC tokens using pathfinding
|
|
34
|
+
*
|
|
35
|
+
* @param options Optional pathfinding options
|
|
36
|
+
* @returns Maximum replenishable amount in atto-circles
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const maxReplenishable = await avatar.balances.getMaxReplenishable();
|
|
41
|
+
* console.log('Can replenish:', CirclesConverter.attoCirclesToCircles(maxReplenishable), 'CRC');
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
getMaxReplenishable: async (options) => {
|
|
45
|
+
const addr = this.address.toLowerCase();
|
|
46
|
+
// Find maximum flow from avatar to itself, targeting personal tokens as destination
|
|
47
|
+
// This effectively asks: "How much can I convert to my own personal tokens?"
|
|
48
|
+
const maxFlow = await this.rpc.pathfinder.findMaxFlow({
|
|
49
|
+
from: addr,
|
|
50
|
+
to: addr,
|
|
51
|
+
toTokens: [addr], // Destination token is sender's own personal CRC
|
|
52
|
+
useWrappedBalances: true, // Include wrapped tokens
|
|
53
|
+
...options,
|
|
54
|
+
});
|
|
55
|
+
return maxFlow;
|
|
56
|
+
},
|
|
57
|
+
/**
|
|
58
|
+
* Replenish unwrapped personal CRC tokens by converting wrapped/other tokens
|
|
59
|
+
*
|
|
60
|
+
* This method uses pathfinding to find the best way to convert your available tokens
|
|
61
|
+
* (including wrapped tokens) into unwrapped ERC1155 personal CRC tokens.
|
|
62
|
+
*
|
|
63
|
+
* Useful when you have wrapped tokens or other people's tokens and want to
|
|
64
|
+
* convert them to your own personal unwrapped tokens for transfers.
|
|
65
|
+
*
|
|
66
|
+
* @param options Optional pathfinding options
|
|
67
|
+
* @returns Transaction receipt
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Convert all available wrapped/other tokens to unwrapped personal CRC
|
|
72
|
+
* const receipt = await avatar.balances.replenish();
|
|
73
|
+
* console.log('Replenished personal tokens, tx hash:', receipt.hash);
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
replenish: async (options) => {
|
|
77
|
+
// Construct replenish transactions using TransferBuilder
|
|
78
|
+
const transactions = await this.transferBuilder.constructReplenish(this.address, options);
|
|
79
|
+
// If no transactions needed, return early
|
|
80
|
+
if (transactions.length === 0) {
|
|
81
|
+
throw SdkError.configError('No tokens available to replenish', { message: 'You may not have any wrapped tokens or convertible tokens' });
|
|
82
|
+
}
|
|
83
|
+
// Execute the constructed transactions
|
|
84
|
+
return await this.runner.sendTransaction(transactions);
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// Transfer methods are inherited from CommonAvatar
|
|
89
|
+
// ============================================================================
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// Group Token Methods
|
|
92
|
+
// ============================================================================
|
|
93
|
+
groupToken = {
|
|
94
|
+
/**
|
|
95
|
+
* Mint group tokens by transferring collateral to the group's mint handler
|
|
96
|
+
* Uses pathfinding to transfer tokens along the trust network, including wrapped tokens
|
|
97
|
+
*
|
|
98
|
+
* @param group The group address to mint tokens from
|
|
99
|
+
* @param amount Amount of tokens to transfer to the mint handler (in atto-circles)
|
|
100
|
+
* @returns Transaction receipt
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* // Mint group tokens by sending 100 CRC to the group's mint handler
|
|
105
|
+
* const receipt = await avatar.groupToken.mint('0xGroupAddress...', BigInt(100e18));
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
mint: async (group, amount) => {
|
|
109
|
+
// Create BaseGroupContract instance to get mint handler
|
|
110
|
+
const groupContract = new BaseGroupContract({
|
|
111
|
+
address: group,
|
|
112
|
+
rpcUrl: this.core.rpcUrl,
|
|
113
|
+
});
|
|
114
|
+
const mintHandler = await groupContract.BASE_MINT_HANDLER();
|
|
115
|
+
// Use transferBuilder to construct transfer to mint handler with pathfinding
|
|
116
|
+
// Include wrapped tokens in pathfinding
|
|
117
|
+
const transactions = await this.transferBuilder.constructAdvancedTransfer(this.address, mintHandler, amount, { useWrappedBalances: true });
|
|
118
|
+
return await this.runner.sendTransaction(transactions);
|
|
119
|
+
},
|
|
120
|
+
/**
|
|
121
|
+
* Get the maximum amount that can be minted for a group
|
|
122
|
+
* This calculates the maximum transferable amount to the group's mint handler
|
|
123
|
+
* including wrapped token balances
|
|
124
|
+
*
|
|
125
|
+
* @param group The group address
|
|
126
|
+
* @returns Maximum mintable amount in atto-circles
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const maxMintable = await avatar.groupToken.getMaxMintableAmount('0xGroupAddress...');
|
|
131
|
+
* console.log('Can mint up to:', maxMintable.toString(), 'atto-circles');
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
getMaxMintableAmount: async (group) => {
|
|
135
|
+
// Create BaseGroupContract instance to get mint handler
|
|
136
|
+
const groupContract = new BaseGroupContract({
|
|
137
|
+
address: group,
|
|
138
|
+
rpcUrl: this.core.rpcUrl,
|
|
139
|
+
});
|
|
140
|
+
const mintHandler = await groupContract.BASE_MINT_HANDLER();
|
|
141
|
+
// Find max flow to mint handler including wrapped tokens
|
|
142
|
+
return await this.rpc.pathfinder.findMaxFlow({
|
|
143
|
+
from: this.address.toLowerCase(),
|
|
144
|
+
to: mintHandler.toLowerCase(),
|
|
145
|
+
useWrappedBalances: true,
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
/**
|
|
149
|
+
* Automatically redeem collateral tokens from a Base Group's treasury
|
|
150
|
+
*
|
|
151
|
+
* Performs automatic redemption by determining trusted collaterals and using pathfinder for optimal flow.
|
|
152
|
+
* Only supports Base Group types. The function uses pathfinder to determine the optimal redemption path
|
|
153
|
+
* and validates that sufficient liquidity exists before attempting redemption.
|
|
154
|
+
*
|
|
155
|
+
* Note: Organizations don't have personal tokens. This method uses the tokens held by the organization
|
|
156
|
+
* (which are other avatars' tokens or other group tokens) to redeem from the specified group.
|
|
157
|
+
*
|
|
158
|
+
* @param group The address of the Base Group from which to redeem collateral tokens
|
|
159
|
+
* @param amount The amount of group tokens to redeem for collateral (must be > 0 and <= max redeemable)
|
|
160
|
+
* @returns A Promise resolving to the transaction receipt upon successful automatic redemption
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* // Redeem 100 group tokens for collateral
|
|
165
|
+
* const receipt = await orgAvatar.groupToken.redeem('0xGroupAddress...', BigInt(100e18));
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
redeem: async (group, amount) => {
|
|
169
|
+
group = group.toLowerCase();
|
|
170
|
+
// Get group information to validate it's a Base Group
|
|
171
|
+
const groupInfo = await this.rpc.token.getTokenInfo(group);
|
|
172
|
+
if (!groupInfo) {
|
|
173
|
+
throw SdkError.configError(`Group not found: ${group}`, { group });
|
|
174
|
+
}
|
|
175
|
+
// Validate it's a Base Group (supports CrcV2_RegisterGroup event type)
|
|
176
|
+
if (groupInfo.tokenType !== 'CrcV2_RegisterGroup') {
|
|
177
|
+
throw SdkError.unsupportedOperation('redeem', 'Only Base Groups support this method');
|
|
178
|
+
}
|
|
179
|
+
// Address of the redeemer (this organization)
|
|
180
|
+
const currentAvatar = this.address.toLowerCase();
|
|
181
|
+
// Create BaseGroupContract instance to get treasury
|
|
182
|
+
const groupContract = new BaseGroupContract({
|
|
183
|
+
address: group,
|
|
184
|
+
rpcUrl: this.core.rpcUrl,
|
|
185
|
+
});
|
|
186
|
+
const treasuryAddress = (await groupContract.BASE_TREASURY()).toLowerCase();
|
|
187
|
+
// Get list of all tokens in the treasury
|
|
188
|
+
const treasuryBalances = await this.rpc.balance.getTokenBalances(treasuryAddress);
|
|
189
|
+
const treasuryTokens = treasuryBalances
|
|
190
|
+
.filter((balance) => balance.isErc1155)
|
|
191
|
+
.map((balance) => balance.tokenAddress.toLowerCase());
|
|
192
|
+
// Get trust relationships to determine expected collateral tokens
|
|
193
|
+
const trustRelationships = await this.rpc.trust.getAggregatedTrustRelations(currentAvatar);
|
|
194
|
+
// Filter for tokens that:
|
|
195
|
+
// 1. Are mutually trusted or trusted by current avatar
|
|
196
|
+
// 2. Exist in the treasury
|
|
197
|
+
const expectedToTokens = trustRelationships
|
|
198
|
+
.filter((trustObject) => {
|
|
199
|
+
if ((trustObject.relation === 'mutuallyTrusts' || trustObject.relation === 'trusts') &&
|
|
200
|
+
treasuryTokens.includes(trustObject.objectAvatar.toLowerCase())) {
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
return false;
|
|
204
|
+
})
|
|
205
|
+
.map((trustObject) => trustObject.objectAvatar.toLowerCase());
|
|
206
|
+
// Check if enough tokens as amount - validate max redeemable
|
|
207
|
+
// Note: Organizations don't have personal tokens, so we use whatever tokens they hold
|
|
208
|
+
const maxRedeemableAmount = await this.rpc.pathfinder.findMaxFlow({
|
|
209
|
+
from: currentAvatar,
|
|
210
|
+
to: currentAvatar,
|
|
211
|
+
useWrappedBalances: false,
|
|
212
|
+
fromTokens: [group],
|
|
213
|
+
toTokens: expectedToTokens,
|
|
214
|
+
});
|
|
215
|
+
if (BigInt(maxRedeemableAmount) < amount) {
|
|
216
|
+
throw ValidationError.invalidAmount(amount, `Specified amount ${amount} exceeds max tokens flow ${maxRedeemableAmount}`);
|
|
217
|
+
}
|
|
218
|
+
// Construct the redemption transfer using TransferBuilder
|
|
219
|
+
const transactions = await this.transferBuilder.constructAdvancedTransfer(currentAvatar, currentAvatar, // Redeem to self
|
|
220
|
+
amount, {
|
|
221
|
+
useWrappedBalances: false,
|
|
222
|
+
fromTokens: [group], // Redeem from group tokens
|
|
223
|
+
toTokens: expectedToTokens, // Receive trusted collateral tokens
|
|
224
|
+
});
|
|
225
|
+
if (!transactions || transactions.length === 0) {
|
|
226
|
+
throw SdkError.operationFailed('groupToken.redeem', 'No transactions generated');
|
|
227
|
+
}
|
|
228
|
+
return await this.runner.sendTransaction(transactions);
|
|
229
|
+
},
|
|
230
|
+
properties: {
|
|
231
|
+
/**
|
|
232
|
+
* Get the owner of a specific group
|
|
233
|
+
* @param group The group address
|
|
234
|
+
* @returns The owner address of the group
|
|
235
|
+
*/
|
|
236
|
+
owner: async (group) => {
|
|
237
|
+
const groupContract = new BaseGroupContract({
|
|
238
|
+
address: group,
|
|
239
|
+
rpcUrl: this.core.rpcUrl,
|
|
240
|
+
});
|
|
241
|
+
return await groupContract.owner();
|
|
242
|
+
},
|
|
243
|
+
/**
|
|
244
|
+
* Get the mint handler address of a specific group
|
|
245
|
+
* @param group The group address
|
|
246
|
+
* @returns The mint handler address
|
|
247
|
+
*/
|
|
248
|
+
mintHandler: async (group) => {
|
|
249
|
+
const groupContract = new BaseGroupContract({
|
|
250
|
+
address: group,
|
|
251
|
+
rpcUrl: this.core.rpcUrl,
|
|
252
|
+
});
|
|
253
|
+
return await groupContract.BASE_MINT_HANDLER();
|
|
254
|
+
},
|
|
255
|
+
/**
|
|
256
|
+
* Get the treasury (redemption handler) address of a specific group
|
|
257
|
+
* @param group The group address
|
|
258
|
+
* @returns The treasury address where redemptions are handled
|
|
259
|
+
*/
|
|
260
|
+
treasury: async (group) => {
|
|
261
|
+
const groupContract = new BaseGroupContract({
|
|
262
|
+
address: group,
|
|
263
|
+
rpcUrl: this.core.rpcUrl,
|
|
264
|
+
});
|
|
265
|
+
return await groupContract.BASE_TREASURY();
|
|
266
|
+
},
|
|
267
|
+
/**
|
|
268
|
+
* Get the service address of a specific group
|
|
269
|
+
* @param group The group address
|
|
270
|
+
* @returns The service address
|
|
271
|
+
*/
|
|
272
|
+
service: async (group) => {
|
|
273
|
+
const groupContract = new BaseGroupContract({
|
|
274
|
+
address: group,
|
|
275
|
+
rpcUrl: this.core.rpcUrl,
|
|
276
|
+
});
|
|
277
|
+
return await groupContract.service();
|
|
278
|
+
},
|
|
279
|
+
/**
|
|
280
|
+
* Get the fee collection address of a specific group
|
|
281
|
+
* @param group The group address
|
|
282
|
+
* @returns The fee collection address
|
|
283
|
+
*/
|
|
284
|
+
feeCollection: async (group) => {
|
|
285
|
+
const groupContract = new BaseGroupContract({
|
|
286
|
+
address: group,
|
|
287
|
+
rpcUrl: this.core.rpcUrl,
|
|
288
|
+
});
|
|
289
|
+
return await groupContract.feeCollection();
|
|
290
|
+
},
|
|
291
|
+
/**
|
|
292
|
+
* Get all membership conditions for a specific group
|
|
293
|
+
* @param group The group address
|
|
294
|
+
* @returns Array of membership condition addresses
|
|
295
|
+
*/
|
|
296
|
+
getMembershipConditions: async (group) => {
|
|
297
|
+
const groupContract = new BaseGroupContract({
|
|
298
|
+
address: group,
|
|
299
|
+
rpcUrl: this.core.rpcUrl,
|
|
300
|
+
});
|
|
301
|
+
const conditions = await groupContract.getMembershipConditions();
|
|
302
|
+
return Array.from(conditions);
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
// Group methods (alias for groupToken)
|
|
307
|
+
group = {
|
|
308
|
+
properties: this.groupToken.properties,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avatar classes for interacting with Circles protocol
|
|
3
|
+
*/
|
|
4
|
+
export { CommonAvatar } from './CommonAvatar';
|
|
5
|
+
export { HumanAvatar } from './HumanAvatar';
|
|
6
|
+
export { OrganisationAvatar } from './OrganisationAvatar';
|
|
7
|
+
export { BaseGroupAvatar } from './BaseGroupAvatar';
|
|
8
|
+
export type { PathfindingOptions } from './CommonAvatar';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/avatars/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Avatar classes for interacting with Circles protocol
|
|
3
|
+
*/
|
|
4
|
+
export { CommonAvatar } from './CommonAvatar';
|
|
5
|
+
export { HumanAvatar } from './HumanAvatar';
|
|
6
|
+
export { OrganisationAvatar } from './OrganisationAvatar';
|
|
7
|
+
export { BaseGroupAvatar } from './BaseGroupAvatar';
|