@kaleidorg/mind 0.6.1 → 0.6.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/recipe/kaleidoswap-atomic.d.ts.map +1 -1
- package/dist/recipe/kaleidoswap-atomic.js +29 -16
- package/dist/recipe/kaleidoswap-atomic.js.map +1 -1
- package/package.json +1 -1
- package/src/funnel.mind.test.ts +3 -5
- package/src/recipe/kaleidoswap-atomic.test.ts +31 -6
- package/src/recipe/kaleidoswap-atomic.ts +37 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kaleidoswap-atomic.d.ts","sourceRoot":"","sources":["../../src/recipe/kaleidoswap-atomic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"kaleidoswap-atomic.d.ts","sourceRoot":"","sources":["../../src/recipe/kaleidoswap-atomic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AA6DxD,eAAO,MAAM,uBAAuB,EAAE,MA0GrC,CAAC"}
|
|
@@ -69,6 +69,12 @@ const SWAP_INTENT = (t) => {
|
|
|
69
69
|
return RGB_CUE.test(t);
|
|
70
70
|
return false;
|
|
71
71
|
};
|
|
72
|
+
// KaleidoSwap atomic is a BTC ↔ RGB venue: BTC settles on Lightning, RGB
|
|
73
|
+
// assets on RGB-over-Lightning. The maker/MCP layer is derived from the asset.
|
|
74
|
+
const layerFor = (asset) => /^btc$/i.test(String(asset)) ? 'BTC_LN' : 'RGB_LN';
|
|
75
|
+
// Render a quote leg as "<amount> <TICKER>" from the MCP quote echo, or undefined
|
|
76
|
+
// if the leg is missing (callers fall back to the user's slot values).
|
|
77
|
+
const quoteLeg = (leg) => leg?.amount_display != null ? `${leg.amount_display}${leg.ticker ? ` ${leg.ticker}` : ''}` : undefined;
|
|
72
78
|
export const kaleidoswapAtomicRecipe = {
|
|
73
79
|
name: 'kaleidoswap-atomic',
|
|
74
80
|
description: 'Swap between BTC and an RGB asset on KaleidoSwap: quote, confirm once, then init (maker) → whitelist (node) → execute (maker).',
|
|
@@ -93,14 +99,21 @@ export const kaleidoswapAtomicRecipe = {
|
|
|
93
99
|
{
|
|
94
100
|
tool: 'kaleidoswap_get_quote',
|
|
95
101
|
as: 'quote',
|
|
96
|
-
args: (ctx) =>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
amount
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
args: (ctx) => {
|
|
103
|
+
// 'to' for buy ("buy 1 USDT" → amount is what you RECEIVE) goes on the
|
|
104
|
+
// to_amount leg; 'from' (sell/swap) goes on from_amount. Layers are
|
|
105
|
+
// derived from the asset. Exactly one amount leg is set.
|
|
106
|
+
const side = ctx.slots.amount_side ?? 'from';
|
|
107
|
+
const base = {
|
|
108
|
+
from_asset_id: ctx.slots.from_asset,
|
|
109
|
+
to_asset_id: ctx.slots.to_asset,
|
|
110
|
+
from_layer: layerFor(ctx.slots.from_asset),
|
|
111
|
+
to_layer: layerFor(ctx.slots.to_asset),
|
|
112
|
+
};
|
|
113
|
+
return side === 'to'
|
|
114
|
+
? { ...base, to_amount: ctx.slots.amount }
|
|
115
|
+
: { ...base, from_amount: ctx.slots.amount };
|
|
116
|
+
},
|
|
104
117
|
},
|
|
105
118
|
// 2. MAKER locks the swap. SwapRequest is flat (asset ids + maker-unit
|
|
106
119
|
// amounts) — sourced straight from the quote result, no re-scaling.
|
|
@@ -112,10 +125,10 @@ export const kaleidoswapAtomicRecipe = {
|
|
|
112
125
|
const q = ctx.results.quote;
|
|
113
126
|
return {
|
|
114
127
|
rfq_id: q?.rfq_id,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
128
|
+
from_asset_id: q?.from_asset?.asset_id,
|
|
129
|
+
from_amount_raw: q?.from_asset?.amount_raw,
|
|
130
|
+
to_asset_id: q?.to_asset?.asset_id,
|
|
131
|
+
to_amount_raw: q?.to_asset?.amount_raw,
|
|
119
132
|
};
|
|
120
133
|
},
|
|
121
134
|
},
|
|
@@ -153,15 +166,15 @@ export const kaleidoswapAtomicRecipe = {
|
|
|
153
166
|
// ONE confirmation, fired after the quote / before init, with the real numbers.
|
|
154
167
|
confirm: (ctx) => {
|
|
155
168
|
const q = ctx.results.quote;
|
|
156
|
-
const from = q?.
|
|
157
|
-
const to = q?.
|
|
169
|
+
const from = quoteLeg(q?.from_asset) ?? `${ctx.slots.amount} ${ctx.slots.from_asset}`;
|
|
170
|
+
const to = quoteLeg(q?.to_asset) ?? String(ctx.slots.to_asset);
|
|
158
171
|
const fee = q?.fee_display ? ` · fee ${q.fee_display}` : '';
|
|
159
172
|
return `Swap ${from} → ${to}${fee} on KaleidoSwap. Proceed?`;
|
|
160
173
|
},
|
|
161
174
|
summary: (ctx) => {
|
|
162
175
|
const q = ctx.results.quote;
|
|
163
|
-
const from = q?.
|
|
164
|
-
const to = q?.
|
|
176
|
+
const from = quoteLeg(q?.from_asset) ?? `${ctx.slots.amount} ${ctx.slots.from_asset}`;
|
|
177
|
+
const to = quoteLeg(q?.to_asset) ?? String(ctx.slots.to_asset);
|
|
165
178
|
const init = ctx.results.init;
|
|
166
179
|
const id = init?.atomic_id || init?.payment_hash || '?';
|
|
167
180
|
return `remember: atomic swap atomic_id=${id} (for later kaleidoswap_atomic_status checks).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kaleidoswap-atomic.js","sourceRoot":"","sources":["../../src/recipe/kaleidoswap-atomic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,2EAA2E;AAC3E,8EAA8E;AAC9E,6CAA6C;AAC7C,kEAAkE;AAClE,8EAA8E;AAC9E,+EAA+E;AAC/E,oDAAoD;AACpD,MAAM,OAAO,GAAG,6DAA6D,CAAC;AAC9E,MAAM,YAAY,GAAG,4BAA4B,CAAC;AAClD,MAAM,WAAW,GAAG,CAAC,CAAS,EAAE,EAAE;IAChC,4EAA4E;IAC5E,qCAAqC;IACrC,IAAI,6EAA6E,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACxG,+DAA+D;IAC/D,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,0EAA0E;IAC1E,6EAA6E;IAC7E,yEAAyE;IACzE,IAAI,4DAA4D,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACvF,IAAI,4FAA4F,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACvH,MAAM,QAAQ,GAAG,oCAAoC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,OAAO,GACX,sCAAsC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9C,wEAAwE;QACxE,yEAAyE;QACzE,CAAC,2FAA2F,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvG,4EAA4E;IAC5E,2EAA2E;IAC3E,IAAI,QAAQ,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAaF,MAAM,CAAC,MAAM,uBAAuB,GAAW;IAC7C,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACT,gIAAgI;IAClI,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;IACjE,KAAK,EAAE;QACL,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sFAAsF,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC3J,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6EAA6E,EAAE,QAAQ,EAAE,IAAI,EAAE;QAChJ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0IAA0I,EAAE;QAC3L,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0HAA0H,EAAE;KACjL;IACD,6EAA6E;IAC7E,yEAAyE;IACzE,0EAA0E;IAC1E,uEAAuE;IACvE,OAAO,EAAE,WAAW;IACpB,iBAAiB,EAAE,IAAI;IACvB,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;IAC9D,KAAK,EAAE;QACL,0EAA0E;QAC1E,6EAA6E;QAC7E;YACE,IAAI,EAAE,uBAAuB;YAC7B,EAAE,EAAE,OAAO;YACX,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"kaleidoswap-atomic.js","sourceRoot":"","sources":["../../src/recipe/kaleidoswap-atomic.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/funnel.mind.test.ts
CHANGED
|
@@ -110,10 +110,8 @@ function buildMind(
|
|
|
110
110
|
// atomic-swap chain (quote read; init/whitelist/execute are spends)
|
|
111
111
|
tool('kaleidoswap_get_quote', {
|
|
112
112
|
rfq_id: 'rfq-1',
|
|
113
|
-
from_asset: { asset_id: 'BTC', ticker: 'BTC',
|
|
114
|
-
to_asset: { asset_id: 'rgb:USDT', ticker: 'USDT',
|
|
115
|
-
from_amount_display: '100,000 sats',
|
|
116
|
-
to_amount_display: '1 USDT',
|
|
113
|
+
from_asset: { asset_id: 'BTC', ticker: 'BTC', layer: 'BTC_LN', amount_raw: 100_000, amount_display: '100,000 sats' },
|
|
114
|
+
to_asset: { asset_id: 'rgb:USDT', ticker: 'USDT', layer: 'RGB_LN', amount_raw: 1_000_000, amount_display: '1 USDT' },
|
|
117
115
|
fee_display: '154 sats',
|
|
118
116
|
}),
|
|
119
117
|
tool('kaleidoswap_atomic_init', { swapstring: 'SWAP/abc/def', payment_hash: 'ph-1' }, /* spend */ true),
|
|
@@ -226,7 +224,7 @@ describe('desktop mind — buy assets via atomic swap', () => {
|
|
|
226
224
|
]);
|
|
227
225
|
// init sources the asset ids + maker-unit amounts straight from the quote.
|
|
228
226
|
const init = calls.find((c) => c.name === 'kaleidoswap_atomic_init')!;
|
|
229
|
-
expect(init.args).toMatchObject({ rfq_id: 'rfq-1',
|
|
227
|
+
expect(init.args).toMatchObject({ rfq_id: 'rfq-1', from_asset_id: 'BTC', to_asset_id: 'rgb:USDT' });
|
|
230
228
|
// execute carries the node pubkey as taker_pubkey + the maker's payment_hash.
|
|
231
229
|
const exec = calls.find((c) => c.name === 'kaleidoswap_atomic_execute')!;
|
|
232
230
|
expect(exec.args).toMatchObject({ swapstring: 'SWAP/abc/def', taker_pubkey: '030637ec', payment_hash: 'ph-1' });
|
|
@@ -31,12 +31,12 @@ function buildStubs(captured: { name: string; args: any }[]) {
|
|
|
31
31
|
});
|
|
32
32
|
return new ToolRegistry([
|
|
33
33
|
new InProcessToolSource('kaleidoswap', [
|
|
34
|
+
// Mirror the REAL kaleido-mcp `kaleidoswap_get_quote` response: each leg
|
|
35
|
+
// echoes asset_id + ticker + layer + amount_raw (integer) + amount_display.
|
|
34
36
|
tool('kaleidoswap_get_quote', {
|
|
35
37
|
rfq_id: 'rfq-1',
|
|
36
|
-
from_asset: { asset_id: 'USDT', ticker: 'USDT',
|
|
37
|
-
to_asset: { asset_id: 'BTC', ticker: 'BTC',
|
|
38
|
-
from_amount_display: '10 USDT',
|
|
39
|
-
to_amount_display: '15,250 sats',
|
|
38
|
+
from_asset: { asset_id: 'USDT', ticker: 'USDT', layer: 'RGB_LN', amount_raw: 10_000_000, amount_display: '10' },
|
|
39
|
+
to_asset: { asset_id: 'BTC', ticker: 'BTC', layer: 'BTC_LN', amount_raw: 15_250_000, amount_display: '15,250 sats' },
|
|
40
40
|
fee_display: '154 sats',
|
|
41
41
|
}),
|
|
42
42
|
tool('kaleidoswap_atomic_init', { swapstring: 'SWAP/abc/def', payment_hash: 'ph-1' }, /* spend */ true),
|
|
@@ -166,8 +166,33 @@ describe('kaleidoswapAtomicRecipe — full chain', () => {
|
|
|
166
166
|
const init = captured.find((c) => c.name === 'kaleidoswap_atomic_init')!;
|
|
167
167
|
expect(init.args).toEqual({
|
|
168
168
|
rfq_id: 'rfq-1',
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
from_asset_id: 'USDT', from_amount_raw: 10_000_000,
|
|
170
|
+
to_asset_id: 'BTC', to_amount_raw: 15_250_000,
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('builds get_quote args matching the kaleido-mcp schema (sell vs buy leg)', async () => {
|
|
175
|
+
// The reported bug: the recipe must emit the MCP tool's field names
|
|
176
|
+
// (from_asset_id/to_asset_id/from_layer/to_layer) and put the amount on the
|
|
177
|
+
// correct leg — to_amount for "buy 1 usdt", from_amount for a sell/swap.
|
|
178
|
+
const sell: { name: string; args: any }[] = [];
|
|
179
|
+
await runRecipe(kaleidoswapAtomicRecipe, 'swap 10 usdt to btc', {
|
|
180
|
+
provider: refusingProvider, tools: buildStubs(sell), onConfirm: async () => ({ approved: true }),
|
|
181
|
+
slots: { from_asset: 'USDT', to_asset: 'BTC', amount: 10, amount_side: 'from' },
|
|
182
|
+
});
|
|
183
|
+
expect(sell.find((c) => c.name === 'kaleidoswap_get_quote')!.args).toEqual({
|
|
184
|
+
from_asset_id: 'USDT', to_asset_id: 'BTC',
|
|
185
|
+
from_layer: 'RGB_LN', to_layer: 'BTC_LN', from_amount: 10,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const buy: { name: string; args: any }[] = [];
|
|
189
|
+
await runRecipe(kaleidoswapAtomicRecipe, 'buy 1 usdt', {
|
|
190
|
+
provider: refusingProvider, tools: buildStubs(buy), onConfirm: async () => ({ approved: true }),
|
|
191
|
+
slots: { from_asset: 'BTC', to_asset: 'USDT', amount: 1, amount_side: 'to' },
|
|
192
|
+
});
|
|
193
|
+
expect(buy.find((c) => c.name === 'kaleidoswap_get_quote')!.args).toEqual({
|
|
194
|
+
from_asset_id: 'BTC', to_asset_id: 'USDT',
|
|
195
|
+
from_layer: 'BTC_LN', to_layer: 'RGB_LN', to_amount: 1,
|
|
171
196
|
});
|
|
172
197
|
});
|
|
173
198
|
|
|
@@ -71,12 +71,24 @@ const SWAP_INTENT = (t: string) => {
|
|
|
71
71
|
|
|
72
72
|
interface QuoteResult {
|
|
73
73
|
rfq_id?: string;
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
// kaleido-mcp `kaleidoswap_get_quote` echoes each leg with the resolved
|
|
75
|
+
// asset_id, ticker, layer, the raw integer amount (amount_raw) and a display string.
|
|
76
|
+
from_asset?: { asset_id?: string; ticker?: string; amount_raw?: number; amount_display?: string };
|
|
77
|
+
to_asset?: { asset_id?: string; ticker?: string; amount_raw?: number; amount_display?: string };
|
|
76
78
|
from_amount_display?: string;
|
|
77
79
|
to_amount_display?: string;
|
|
78
80
|
fee_display?: string;
|
|
79
81
|
}
|
|
82
|
+
|
|
83
|
+
// KaleidoSwap atomic is a BTC ↔ RGB venue: BTC settles on Lightning, RGB
|
|
84
|
+
// assets on RGB-over-Lightning. The maker/MCP layer is derived from the asset.
|
|
85
|
+
const layerFor = (asset: unknown): string =>
|
|
86
|
+
/^btc$/i.test(String(asset)) ? 'BTC_LN' : 'RGB_LN';
|
|
87
|
+
|
|
88
|
+
// Render a quote leg as "<amount> <TICKER>" from the MCP quote echo, or undefined
|
|
89
|
+
// if the leg is missing (callers fall back to the user's slot values).
|
|
90
|
+
const quoteLeg = (leg?: { ticker?: string; amount_display?: string }): string | undefined =>
|
|
91
|
+
leg?.amount_display != null ? `${leg.amount_display}${leg.ticker ? ` ${leg.ticker}` : ''}` : undefined;
|
|
80
92
|
interface InitResult { swapstring?: string; payment_hash?: string; atomic_id?: string }
|
|
81
93
|
interface NodeInfo { pubkey?: string }
|
|
82
94
|
|
|
@@ -105,14 +117,21 @@ export const kaleidoswapAtomicRecipe: Recipe = {
|
|
|
105
117
|
{
|
|
106
118
|
tool: 'kaleidoswap_get_quote',
|
|
107
119
|
as: 'quote',
|
|
108
|
-
args: (ctx) =>
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
amount
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
120
|
+
args: (ctx) => {
|
|
121
|
+
// 'to' for buy ("buy 1 USDT" → amount is what you RECEIVE) goes on the
|
|
122
|
+
// to_amount leg; 'from' (sell/swap) goes on from_amount. Layers are
|
|
123
|
+
// derived from the asset. Exactly one amount leg is set.
|
|
124
|
+
const side = ctx.slots.amount_side ?? 'from';
|
|
125
|
+
const base = {
|
|
126
|
+
from_asset_id: ctx.slots.from_asset,
|
|
127
|
+
to_asset_id: ctx.slots.to_asset,
|
|
128
|
+
from_layer: layerFor(ctx.slots.from_asset),
|
|
129
|
+
to_layer: layerFor(ctx.slots.to_asset),
|
|
130
|
+
};
|
|
131
|
+
return side === 'to'
|
|
132
|
+
? { ...base, to_amount: ctx.slots.amount }
|
|
133
|
+
: { ...base, from_amount: ctx.slots.amount };
|
|
134
|
+
},
|
|
116
135
|
},
|
|
117
136
|
// 2. MAKER locks the swap. SwapRequest is flat (asset ids + maker-unit
|
|
118
137
|
// amounts) — sourced straight from the quote result, no re-scaling.
|
|
@@ -124,10 +143,10 @@ export const kaleidoswapAtomicRecipe: Recipe = {
|
|
|
124
143
|
const q = ctx.results.quote as QuoteResult | undefined;
|
|
125
144
|
return {
|
|
126
145
|
rfq_id: q?.rfq_id,
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
146
|
+
from_asset_id: q?.from_asset?.asset_id,
|
|
147
|
+
from_amount_raw: q?.from_asset?.amount_raw,
|
|
148
|
+
to_asset_id: q?.to_asset?.asset_id,
|
|
149
|
+
to_amount_raw: q?.to_asset?.amount_raw,
|
|
131
150
|
};
|
|
132
151
|
},
|
|
133
152
|
},
|
|
@@ -165,15 +184,15 @@ export const kaleidoswapAtomicRecipe: Recipe = {
|
|
|
165
184
|
// ONE confirmation, fired after the quote / before init, with the real numbers.
|
|
166
185
|
confirm: (ctx: RecipeContext) => {
|
|
167
186
|
const q = ctx.results.quote as QuoteResult | undefined;
|
|
168
|
-
const from = q?.
|
|
169
|
-
const to = q?.
|
|
187
|
+
const from = quoteLeg(q?.from_asset) ?? `${ctx.slots.amount} ${ctx.slots.from_asset}`;
|
|
188
|
+
const to = quoteLeg(q?.to_asset) ?? String(ctx.slots.to_asset);
|
|
170
189
|
const fee = q?.fee_display ? ` · fee ${q.fee_display}` : '';
|
|
171
190
|
return `Swap ${from} → ${to}${fee} on KaleidoSwap. Proceed?`;
|
|
172
191
|
},
|
|
173
192
|
summary: (ctx) => {
|
|
174
193
|
const q = ctx.results.quote as QuoteResult | undefined;
|
|
175
|
-
const from = q?.
|
|
176
|
-
const to = q?.
|
|
194
|
+
const from = quoteLeg(q?.from_asset) ?? `${ctx.slots.amount} ${ctx.slots.from_asset}`;
|
|
195
|
+
const to = quoteLeg(q?.to_asset) ?? String(ctx.slots.to_asset);
|
|
177
196
|
const init = ctx.results.init as InitResult | undefined;
|
|
178
197
|
const id = init?.atomic_id || init?.payment_hash || '?';
|
|
179
198
|
return `remember: atomic swap atomic_id=${id} (for later kaleidoswap_atomic_status checks).
|