@ixo/oracle-runtime-workers 0.33.0 → 0.33.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ixo/oracle-runtime-workers",
|
|
3
|
-
"version": "0.33.
|
|
3
|
+
"version": "0.33.2",
|
|
4
4
|
"description": "QiForge oracle runtime for Cloudflare Workers — Durable Object per user (SQLite in WASM over DO storage), Matrix E2EE gateway Durable Object, Hono HTTP/SSE shell.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"!src/plugins/pod-creator/test-fixtures.ts"
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@ixo/action-protocol": "0.9.
|
|
37
|
+
"@ixo/action-protocol": "0.9.1",
|
|
38
38
|
"@blocknote/server-util": "0.29.1",
|
|
39
39
|
"@composio/core": "0.10.0",
|
|
40
40
|
"@composio/langchain": "0.9.2",
|
|
@@ -115,12 +115,14 @@ export interface HubActionTransport {
|
|
|
115
115
|
* An Auth Hub older than this runtime's version checks `?version=` against
|
|
116
116
|
* its closed list (1 to 6 on 0.8.0, 1 to 5 on 0.7.0) and answers every call
|
|
117
117
|
* that declares a version it does not know with 400 `invalid_request`,
|
|
118
|
-
* before anything else. This runtime then steps down
|
|
118
|
+
* before anything else. This runtime's capabilities read then steps down
|
|
119
119
|
* (`HUB_PROTOCOL_VERSIONS`: 7, then 6, then 5) to the highest version that
|
|
120
|
-
* Hub answers
|
|
121
|
-
* Auth Hub is rolled out: the group
|
|
122
|
-
* at 5)
|
|
123
|
-
*
|
|
120
|
+
* Hub answers, and every other call uses that version (every Hub action
|
|
121
|
+
* the lower level has keeps working while Auth Hub is rolled out: the group
|
|
122
|
+
* steps at 6, the level-6 chain types too at 5); it asks for 7 again after
|
|
123
|
+
* `HUB_PROTOCOL_RECHECK_MS`. Another read refused at that version never
|
|
124
|
+
* lowers it (`atSettledVersion`). A Hub that refuses 5 too is told apart
|
|
125
|
+
* with `HUB_UPDATE_REQUIRED`.
|
|
124
126
|
*/
|
|
125
127
|
const HUB_PROTOCOL_VERSION = '7';
|
|
126
128
|
/** The lowest version this runtime works at: 7 without the group steps and the level-6 chain types. */
|
|
@@ -144,6 +146,14 @@ export const HUB_PROTOCOL_RECHECK_MS = 10 * 60_000;
|
|
|
144
146
|
* callbacks pick the outcomes up once the Hub is updated.
|
|
145
147
|
*/
|
|
146
148
|
export const HUB_UPDATE_REQUIRED = `Auth Hub must be updated before this oracle can use Hub actions: it does not accept protocol version ${HUB_PROTOCOL_LOWEST_VERSION}, the lowest this runtime works with (invalid_request). Tell the person this is not available right now; retrying or changing the fields will not help.`;
|
|
149
|
+
/**
|
|
150
|
+
* A read (options, status) Auth Hub refused at the version its
|
|
151
|
+
* capabilities read accepts: a fault on that route, not an older Hub.
|
|
152
|
+
*/
|
|
153
|
+
export function hubReadRefused(version: string): string {
|
|
154
|
+
return `Auth Hub refused this read at protocol version ${version}, which it accepts for this oracle's other calls (invalid_request). Tell the person this is not available right now and try again later; changing the fields will not help.`;
|
|
155
|
+
}
|
|
156
|
+
|
|
147
157
|
/** Every Hub call but a chain-transaction prepare. */
|
|
148
158
|
const HUB_TIMEOUT_MS = 10_000;
|
|
149
159
|
/**
|
|
@@ -198,12 +208,15 @@ export class HubActionClient {
|
|
|
198
208
|
}
|
|
199
209
|
|
|
200
210
|
/**
|
|
201
|
-
*
|
|
202
|
-
* the same read at each lower version in turn
|
|
203
|
-
* and the version it answered is remembered for
|
|
204
|
-
* `HUB_PROTOCOL_RECHECK_MS`. Only
|
|
205
|
-
* nothing, while a prepare's 400 can be a
|
|
206
|
-
*
|
|
211
|
+
* The capabilities read at the current version; when Auth Hub refuses it
|
|
212
|
+
* as unknown, the same read at each lower version in turn
|
|
213
|
+
* (`HUB_PROTOCOL_VERSIONS`), and the version it answered is remembered for
|
|
214
|
+
* `HUB_PROTOCOL_RECHECK_MS`. Only the capabilities read decides the
|
|
215
|
+
* version: a refused read changed nothing, while a prepare's 400 can be a
|
|
216
|
+
* real refusal of its operation, and another route refusing a version
|
|
217
|
+
* (an options route bug once refused 7 and 6) must never downgrade the
|
|
218
|
+
* operations. A Hub that refuses the lowest version too answers
|
|
219
|
+
* `HUB_UPDATE_REQUIRED`.
|
|
207
220
|
*/
|
|
208
221
|
private async negotiated<T>(
|
|
209
222
|
read: (version: HubProtocolVersion) => Promise<T>,
|
|
@@ -229,6 +242,37 @@ export class HubActionClient {
|
|
|
229
242
|
throw new Error('No Hub protocol version to read at');
|
|
230
243
|
}
|
|
231
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Another read (options, status) at the version the capabilities read
|
|
247
|
+
* settled on. When Auth Hub refuses it as unknown, the capabilities read
|
|
248
|
+
* settles the version again (a Hub rolled back since); only when that
|
|
249
|
+
* changes the version is the read tried once more, at the new version.
|
|
250
|
+
* Otherwise this read fails on its own (`hubReadRefused`) and the version
|
|
251
|
+
* the operations use stays as it is. `timeoutMs` bounds that capabilities
|
|
252
|
+
* read as it bounds this one.
|
|
253
|
+
*/
|
|
254
|
+
private async atSettledVersion<T>(
|
|
255
|
+
read: (version: HubProtocolVersion) => Promise<T>,
|
|
256
|
+
timeoutMs = HUB_TIMEOUT_MS,
|
|
257
|
+
): Promise<T> {
|
|
258
|
+
const version = this.protocolVersion;
|
|
259
|
+
try {
|
|
260
|
+
return await read(version);
|
|
261
|
+
} catch (error) {
|
|
262
|
+
if (!isUpdateRequired(error)) throw error;
|
|
263
|
+
}
|
|
264
|
+
await this.capabilities(timeoutMs);
|
|
265
|
+
const settled = this.protocolVersion;
|
|
266
|
+
if (settled === version)
|
|
267
|
+
throw new HubActionRefused(
|
|
268
|
+
'refused',
|
|
269
|
+
hubReadRefused(version),
|
|
270
|
+
undefined,
|
|
271
|
+
400,
|
|
272
|
+
);
|
|
273
|
+
return read(settled);
|
|
274
|
+
}
|
|
275
|
+
|
|
232
276
|
/**
|
|
233
277
|
* `subject`: what a refused prepare is called in the model's words;
|
|
234
278
|
* `steps`: a chain transaction's message types, for the words of a refusal
|
|
@@ -343,7 +387,7 @@ export class HubActionClient {
|
|
|
343
387
|
// Options version 3 (asked at the protocol version; version 4 answers
|
|
344
388
|
// the same): version 2 plus the owner's bank tokens
|
|
345
389
|
// (`transfer.tokens`), which any-token transfers are chosen from.
|
|
346
|
-
const options = await this.
|
|
390
|
+
const options = await this.atSettledVersion(async (version) => {
|
|
347
391
|
const query = new URLSearchParams({
|
|
348
392
|
bindingId: input.bindingId,
|
|
349
393
|
bindingRevision: String(input.bindingRevision),
|
|
@@ -391,12 +435,14 @@ export class HubActionClient {
|
|
|
391
435
|
): Promise<HubActionStatus> {
|
|
392
436
|
if (!/^[A-Za-z0-9_-]{32}$/.test(id))
|
|
393
437
|
throw new Error('Invalid Hub action id');
|
|
394
|
-
const raw = await this.
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
438
|
+
const raw = await this.atSettledVersion(
|
|
439
|
+
(version) =>
|
|
440
|
+
this.send(
|
|
441
|
+
`/api/internal/actions/operations/${id}?version=${version}`,
|
|
442
|
+
undefined,
|
|
443
|
+
timeoutMs,
|
|
444
|
+
),
|
|
445
|
+
timeoutMs,
|
|
400
446
|
);
|
|
401
447
|
if (!isRecord(raw)) throw new Error('Invalid Hub action status');
|
|
402
448
|
const value = raw;
|
|
@@ -406,6 +406,16 @@ const HUB_TRANSIENT_CODES: Readonly<Record<number, readonly string[]>> = {
|
|
|
406
406
|
503: ['transfer_unavailable'],
|
|
407
407
|
};
|
|
408
408
|
|
|
409
|
+
/**
|
|
410
|
+
* Auth Hub's 409 `sequence_reserved`: another card of the owner's is still
|
|
411
|
+
* waiting for their review and holds the account's next transaction, so no
|
|
412
|
+
* new card can be made until that one is approved or declined. Plain words
|
|
413
|
+
* and the next step; the account's sequence is never named (the model
|
|
414
|
+
* repeated "reserved transaction sequence" to the person on devnet).
|
|
415
|
+
*/
|
|
416
|
+
export const PENDING_CARD_WORDS =
|
|
417
|
+
'The owner already has another card waiting for their review, so this one cannot be prepared yet. Tell them, in these words or close to them: “You already have another card waiting for your review. Approve or decline that one first, then I can prepare this.” Do not retry until they have, and never mention sequences or anything technical.';
|
|
418
|
+
|
|
409
419
|
function hubErrorBody(
|
|
410
420
|
body: unknown,
|
|
411
421
|
): { error: string; reason?: string } | null {
|
|
@@ -436,6 +446,8 @@ const HUB_REASON_MAX = 200;
|
|
|
436
446
|
* `not_authorized`, `operation_not_registered`: the transfer or
|
|
437
447
|
* transaction as asked cannot go ahead (with the Hub's reason, quoted and
|
|
438
448
|
* labelled as data, see `quoteHubText`);
|
|
449
|
+
* - 409 `sequence_reserved`: another card is waiting for the owner's
|
|
450
|
+
* review; approve or decline it first (`PENDING_CARD_WORDS`);
|
|
439
451
|
* - 409 `sequence_mismatch`, 503 `transfer_unavailable`: temporary, try
|
|
440
452
|
* again shortly;
|
|
441
453
|
* - any other 409: the account may not use this operation (deterministic,
|
|
@@ -484,10 +496,16 @@ export function hubPrepareRefusal(
|
|
|
484
496
|
undefined,
|
|
485
497
|
status,
|
|
486
498
|
);
|
|
499
|
+
if (status === 409 && parsed.error === 'sequence_reserved')
|
|
500
|
+
return new HubActionRefused('refused', PENDING_CARD_WORDS, undefined, 409);
|
|
487
501
|
if (HUB_TRANSIENT_CODES[status]?.includes(parsed.error))
|
|
488
502
|
return new HubActionRefused(
|
|
489
503
|
'refused',
|
|
490
|
-
|
|
504
|
+
// A sequence race is named by its effect only: the code would read as
|
|
505
|
+
// jargon if repeated to the person.
|
|
506
|
+
parsed.error === 'sequence_mismatch'
|
|
507
|
+
? 'Auth Hub could not prepare this just now because the account changed while it was being prepared; try again shortly.'
|
|
508
|
+
: `Auth Hub is temporarily unavailable for this (${parsed.error}); try again shortly.`,
|
|
491
509
|
undefined,
|
|
492
510
|
status,
|
|
493
511
|
);
|
|
@@ -103,6 +103,13 @@ const SERVICE_REF =
|
|
|
103
103
|
*/
|
|
104
104
|
const LINKED_ENTITY_ADDRESS =
|
|
105
105
|
/^(?:\{id\}#)?ixo1(?:[023456789acdefghjklmnpqrstuvwxyz]{38}|[023456789acdefghjklmnpqrstuvwxyz]{58})$/;
|
|
106
|
+
/**
|
|
107
|
+
* Who receives coins or impact tokens: a 20-byte account or a 32-byte
|
|
108
|
+
* contract address (a group's own account, its treasury). Never a signer or
|
|
109
|
+
* identity field.
|
|
110
|
+
*/
|
|
111
|
+
const RECIPIENT_ADDRESS =
|
|
112
|
+
/^ixo1(?:[023456789acdefghjklmnpqrstuvwxyz]{38}|[023456789acdefghjklmnpqrstuvwxyz]{58})$/;
|
|
106
113
|
/** A 32-byte contract address (a group and its proposal list): `ixo1` and 58 characters. */
|
|
107
114
|
const CONTRACT_ADDRESS = /^ixo1[023456789acdefghjklmnpqrstuvwxyz]{58}$/;
|
|
108
115
|
/**
|
|
@@ -193,6 +200,14 @@ const address = (what: string) =>
|
|
|
193
200
|
'A 20-byte ixo1… account address (42 characters); contract addresses are refused.',
|
|
194
201
|
)
|
|
195
202
|
.describe(`${what} (an ixo1… account address).`);
|
|
203
|
+
const recipient = (what: string) =>
|
|
204
|
+
z
|
|
205
|
+
.string()
|
|
206
|
+
.regex(
|
|
207
|
+
RECIPIENT_ADDRESS,
|
|
208
|
+
'An ixo1… account address (42 characters), or a group’s own address (62 characters, `dao` in chain_lookup daos or dao_proposals), copied exactly.',
|
|
209
|
+
)
|
|
210
|
+
.describe(`${what} (an ixo1… account address, or a group’s own address).`);
|
|
196
211
|
const validator = (what: string) =>
|
|
197
212
|
z
|
|
198
213
|
.string()
|
|
@@ -519,11 +534,12 @@ const OWNER_CATALOG = {
|
|
|
519
534
|
"Sends coins from the owner's wallet to `toAddress`, alone (a single coin send) or as a step of a batch.",
|
|
520
535
|
'`amount` is the amount as the user said it, in the token’s display units ("1.5" for 1.5 IXO): a plain decimal, never base units. The runtime looks the token up in the owner’s token list (hub_action_options `transfer.tokens`), converts the amount with the listed `decimals`, and refuses a token not in the list, more digits after the point than the token has, zero, and more than the listed balance (the bank and stake steps of one token together).',
|
|
521
536
|
'`denom` is optional and defaults to uixo (IXO, 6 decimals). For another token copy its `denom` exactly from `transfer.tokens` (never guess an `ibc/…` hash); name the full denom to the owner for anything but IXO, and say when the token is unverified (it lists 0 decimals: its amount is a whole number of base units).',
|
|
522
|
-
'
|
|
537
|
+
'`toAddress` may also be a group’s own address (62 characters): coins sent there go to the group’s treasury. Find it with chain_lookup daos or dao_proposals (`dao`) when the owner names the group, and say the group’s name.',
|
|
538
|
+
'Say it like: “Send 1.5 IXO to Thandi (ixo1qy…lvf0).” or “Send 2 IXO to the Auth Hub drill group.”',
|
|
523
539
|
].join(' '),
|
|
524
540
|
schema: z.strictObject({
|
|
525
541
|
type: z.literal('cosmos.bank.send'),
|
|
526
|
-
toAddress:
|
|
542
|
+
toAddress: recipient('The recipient'),
|
|
527
543
|
amount: z
|
|
528
544
|
.string()
|
|
529
545
|
.max(80)
|
|
@@ -596,10 +612,10 @@ const OWNER_CATALOG = {
|
|
|
596
612
|
'ixo.token.transfer': {
|
|
597
613
|
summary:
|
|
598
614
|
"move IXO impact tokens (1155-style token ids, whole amounts) from the owner's wallet.",
|
|
599
|
-
rules: `Moves IXO impact tokens (1155-style: each line a token \`id\` of 32 hex characters and a whole \`amount\`, 1 to ${CHAIN_TX_MAX_TOKEN_LINES} lines) from the owner’s wallet to \`recipient
|
|
615
|
+
rules: `Moves IXO impact tokens (1155-style: each line a token \`id\` of 32 hex characters and a whole \`amount\`, 1 to ${CHAIN_TX_MAX_TOKEN_LINES} lines) from the owner’s wallet to \`recipient\` (an account, or a group’s own address from chain_lookup daos or dao_proposals). Impact tokens have no decimals: an amount is a whole number of tokens. All tokens in one message must come from one token contract. These are not the IXO coin: coins go through \`cosmos.bank.send\`. Say it like: “Give 3 of your carbon credits to Thandi (ixo1qy…lvf0).”`,
|
|
600
616
|
schema: z.strictObject({
|
|
601
617
|
type: z.literal('ixo.token.transfer'),
|
|
602
|
-
recipient:
|
|
618
|
+
recipient: recipient('The recipient'),
|
|
603
619
|
tokens: z
|
|
604
620
|
.array(
|
|
605
621
|
z.strictObject({
|
|
@@ -1315,7 +1331,7 @@ const GROUP_CATALOG = {
|
|
|
1315
1331
|
'daodao.proposal.execute': {
|
|
1316
1332
|
summary:
|
|
1317
1333
|
'carry out a group proposal that passed, so the group’s own account does what it says.',
|
|
1318
|
-
rules: `${GROUP_RULES} Carries out a proposal that passed (\`canRun\` in dao_proposals): the group’s own account then does the proposal’s actions, which the review card lists. On a proposal list the group switched off (\`listDisabled\`), a proposal with actions can’t be carried out. Only when the owner asks for it. Tell them what the proposal does (its title) before preparing. Some groups let only members carry proposals out. Auth Hub tries it first and refuses the card when the actions would fail now (in most groups a failed run marks the proposal failed for good), for example when the group doesn’t hold enough; tell the owner it can be tried again once that is fixed. It costs the owner only the network fee; a deposit paid with the proposal goes back to whoever proposed it unless the group keeps deposits (the review card says). After it goes through (hub_action_status), read the receipt’s \`groupActions\`: \`"failed"\` means the proposal’s actions did not happen and it can’t be tried again; never say it is done. \`"unknown"\`: check its status with chain_lookup dao_proposals before saying anything. Say it like: “Carry out proposal A3, ‘Pay Thandi’, in Clean Water Group: the group sends Thandi 500 IXO. This can’t be undone.”`,
|
|
1334
|
+
rules: `${GROUP_RULES} Carries out a proposal that passed (\`canRun\` in dao_proposals): the group’s own account then does the proposal’s actions, which the review card lists. A proposal with no actions (one that asked for agreement only) is simply marked as carried out: never describe an action for it; say “This just marks it as carried out; nothing else happens.” On a proposal list the group switched off (\`listDisabled\`), a proposal with actions can’t be carried out. Only when the owner asks for it. Tell them what the proposal does (its title) before preparing. Some groups let only members carry proposals out. Auth Hub tries it first and refuses the card when the actions would fail now (in most groups a failed run marks the proposal failed for good), for example when the group doesn’t hold enough; tell the owner it can be tried again once that is fixed. It costs the owner only the network fee; a deposit paid with the proposal goes back to whoever proposed it unless the group keeps deposits (the review card says). After it goes through (hub_action_status), read the receipt’s \`groupActions\`: \`"failed"\` means the proposal’s actions did not happen and it can’t be tried again; never say it is done. \`"unknown"\`: check its status with chain_lookup dao_proposals before saying anything. Say it like: “Carry out proposal A3, ‘Pay Thandi’, in Clean Water Group: the group sends Thandi 500 IXO. This can’t be undone.”`,
|
|
1319
1335
|
schema: z
|
|
1320
1336
|
.strictObject({
|
|
1321
1337
|
type: z.literal('daodao.proposal.execute'),
|
|
@@ -1374,7 +1390,7 @@ export const CHAIN_TX_CATALOG = {
|
|
|
1374
1390
|
|
|
1375
1391
|
/** What every message type shares, returned once by describe_chain_messages. */
|
|
1376
1392
|
export const CHAIN_TX_GENERAL_RULES = [
|
|
1377
|
-
'Addresses are 20-byte `ixo1…` account addresses
|
|
1393
|
+
'Addresses are 20-byte `ixo1…` account addresses, except where a type says otherwise: a coin send or impact-token transfer may go to a group’s own address, and the group steps take the group’s and its proposal list’s addresses (32-byte `ixo1…` contract addresses, 62 characters); validators `ixovaloper1…`, entities `did:ixo:entity:…`. Copy every id, address and number exactly from a lookup (chain_lookup, hub_action_options) or from the owner; never invent or guess one. Ids (`claimId`, `collectionId`, token `id`, proofs) use only letters, digits and `: . _ / -`.',
|
|
1378
1394
|
'Give only the fields listed for a type: the runtime adds the chain, the network, the signer and the owner’s own DID and address where a message needs them, and Auth Hub sets the fee. Amounts: coin sends and stakes are what the owner says in the token’s units ("100" IXO); impact tokens are whole tokens; collection payments are base units (1 IXO = 1000000 uixo). Dates are RFC 3339 with Z or an offset, from the owner’s time zone.',
|
|
1379
1395
|
`Up to ${CHAIN_TX_MAX_MESSAGES} messages per transaction, run in the order given (put them in the order the owner said them, and keep one decision in one card); all succeed or none do. A group step (a vote, carrying out or closing a group proposal, a new group proposal) goes alone on its card. A step that needs something stored first (a dispute statement, a profile, a document) can only be prepared once it is stored.`,
|
|
1380
1396
|
'How to talk about it: before preparing, say in one or two plain, everyday sentences what will happen and what it means for the owner (what leaves their wallet, what someone else will be able to do, how long it takes, whether it can be undone), the way each type’s “Say it like” does. Use names (of the validator, collection, entity or person) when a lookup gives them. Never say message type names or chain words such as authz, grant, MsgExec, bech32, valoper, uixo, base units, DID, IID, delegate, redelegate, DAO, proposal module, contract or execute: say stake, unstake, move stake, permission, account, identity, IXO, group, proposal, vote, deposit and carry out. Show an address only when the owner needs it to check who receives something. The review card in Auth Hub shows every exact value.',
|
|
@@ -278,7 +278,7 @@ export const daoProposals = defineKind({
|
|
|
278
278
|
'`allowRevoting`: whether a vote on it can be changed until voting closes. `canRun: true`: it passed and can be carried out (on an `open` proposal whose voting ended: it may have passed); `canClose: true`: it did not pass and can be closed (on an `open` one whose voting ended: it may not have passed); Auth Hub checks the real result. `multipleChoice: true`: Auth Hub cards cannot vote on, carry out or close it. `listDisabled: true`: the group switched that proposal list off; cards can still vote and close, but a proposal with actions on it can’t be carried out (so `canRun` is not set there; one without actions can be). Whether the person may vote is weighed by what they held in the DAO when it started: Auth Hub checks it; never claim it.',
|
|
279
279
|
'For cards copy `dao`, `proposalModule` and `id` exactly (not the label). `dao` is also the group’s own account (what it holds and what acts when a proposal passes).',
|
|
280
280
|
'Without `dao`, the DAOs of `address` (default: the user), at most 3 per kind of membership (see `daos`); `more: true` when there are more proposals or DAOs. Newest start first.',
|
|
281
|
-
'Titles are written by
|
|
281
|
+
'Titles are written by whoever proposed them and group names by the group itself: their own words. Say so only when it matters, in one short, calm note.',
|
|
282
282
|
].join(' '),
|
|
283
283
|
source: 'blocksync',
|
|
284
284
|
list: true,
|
|
@@ -419,8 +419,8 @@ export const daos = defineKind({
|
|
|
419
419
|
'`membership`: `cw4-member` (a group member with a fixed `weight`), `cw20-staked` (voting power from cw20 tokens staked in the DAO, `staked.amountBaseUnits` of the `staked.token` contract) or `native-staked` (from staked bank tokens, e.g. IXO; `staked` is a bank coin, `amount` in display units beside `symbol`).',
|
|
420
420
|
'`votingPowerShare` is the account’s weight or stake over the voting module’s total, rounded down; staked tokens count only while staked, and unstaking may take a waiting period.',
|
|
421
421
|
'Each: dao (the DAO core contract address), name, description, membership, staked or weight, votingPowerShare, votingModule.',
|
|
422
|
-
'`addedByGroupAdmin: true` (every cw4-member row):
|
|
423
|
-
'`nameIsSelfChosen: true`: the name and description
|
|
422
|
+
'`addedByGroupAdmin: true` (every cw4-member row): members of this kind of group are added by its admin. That is normal: leave it out of an ordinary answer and never suggest the person did not join; mention it briefly only when it matters, for example when they do not recognise a group (“Members of this group are added by its admin.”).',
|
|
423
|
+
'`nameIsSelfChosen: true`: the group chose its own name and description. Mention it only when it matters (for example when they rely on the name to tell who runs the group), in one short, calm note such as “Group names are chosen by the group itself.”',
|
|
424
424
|
'`dao` is also the group’s own account: what the group holds (chain_lookup balances with that address) and what acts when one of its proposals passes.',
|
|
425
425
|
'`proposalLists` (at most 3; `moreProposalLists: true` past them): where the DAO takes proposals, each `proposalModule` (its address), `prefix` (the letter before proposal numbers, A in A3), `votingTime`, `allowRevoting` (whether a vote can be changed until voting closes), `membersOnly: true` (only members may propose), `membersOnlyCarryOut: true` (only members may carry out a passed proposal), and `deposit` when proposing takes one: a bank coin (`amount` beside `symbol`) or a cw20 amount with `cardCannotPay: true`, with `refundPolicy` (`only_passed`: back only if it passes and is carried out, `always`: back when carried out or closed, `never`: not back). `multipleChoice: true`: Auth Hub cards cannot use that list. `disabled: true`: the group switched it off: no new proposals through it, and its proposals with actions can’t be carried out (votes and closes still work).',
|
|
426
426
|
'NFT (cw721) staking is not indexed here. Ask `dao_proposals` for what the DAOs are voting on.',
|