@ripplesdotrun/agent-sdk 0.1.0 → 0.1.1
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/LICENSE +21 -0
- package/README.md +6 -2
- package/dist/abi.d.ts +106 -48
- package/dist/abi.js +29 -6
- package/dist/agent.d.ts +30 -6
- package/dist/agent.js +246 -35
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +9 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ripples
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -11,13 +11,17 @@ mint and nobody, including the person who created it, can raise those limits aft
|
|
|
11
11
|
npm install @ripplesdotrun/agent-sdk viem
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
ESM only, Node 20 or newer.
|
|
15
|
+
|
|
14
16
|
## Launch one
|
|
15
17
|
|
|
16
18
|
```ts
|
|
17
19
|
import { privateKeyToAccount } from "viem/accounts";
|
|
18
20
|
import { createRipplesAgent } from "@ripplesdotrun/agent-sdk";
|
|
19
21
|
|
|
20
|
-
const agent = createRipplesAgent({
|
|
22
|
+
const agent = createRipplesAgent({
|
|
23
|
+
account: privateKeyToAccount(process.env.KEY as `0x${string}`),
|
|
24
|
+
});
|
|
21
25
|
|
|
22
26
|
const { treasury, token, market, collection } = await agent.launch({
|
|
23
27
|
runway: "0.05",
|
|
@@ -55,7 +59,7 @@ await agent.claim(); // the trade fees and the collection's share of
|
|
|
55
59
|
|
|
56
60
|
await agent.charter(); // the limits, which never change
|
|
57
61
|
await agent.budget(); // what is left of today's, on the UTC day
|
|
58
|
-
await agent.activity(); //
|
|
62
|
+
await agent.activity(); // what it has done, newest first, over a block range
|
|
59
63
|
```
|
|
60
64
|
|
|
61
65
|
## The charter
|
package/dist/abi.d.ts
CHANGED
|
@@ -291,6 +291,62 @@ export declare const AGENT_FACTORY_ABI: readonly [{
|
|
|
291
291
|
readonly name: "ZeroAddress";
|
|
292
292
|
readonly type: "error";
|
|
293
293
|
readonly inputs: readonly [];
|
|
294
|
+
}, {
|
|
295
|
+
readonly name: "EmptyURI";
|
|
296
|
+
readonly type: "error";
|
|
297
|
+
readonly inputs: readonly [];
|
|
298
|
+
}, {
|
|
299
|
+
readonly name: "InvalidAllocation";
|
|
300
|
+
readonly type: "error";
|
|
301
|
+
readonly inputs: readonly [];
|
|
302
|
+
}, {
|
|
303
|
+
readonly name: "InvalidLockWindow";
|
|
304
|
+
readonly type: "error";
|
|
305
|
+
readonly inputs: readonly [];
|
|
306
|
+
}, {
|
|
307
|
+
readonly name: "InvalidTokenIdentity";
|
|
308
|
+
readonly type: "error";
|
|
309
|
+
readonly inputs: readonly [];
|
|
310
|
+
}, {
|
|
311
|
+
readonly name: "InvalidVesting";
|
|
312
|
+
readonly type: "error";
|
|
313
|
+
readonly inputs: readonly [];
|
|
314
|
+
}, {
|
|
315
|
+
readonly name: "InvalidWindow";
|
|
316
|
+
readonly type: "error";
|
|
317
|
+
readonly inputs: readonly [];
|
|
318
|
+
}, {
|
|
319
|
+
readonly name: "PriceOutOfRange";
|
|
320
|
+
readonly type: "error";
|
|
321
|
+
readonly inputs: readonly [];
|
|
322
|
+
}, {
|
|
323
|
+
readonly name: "QuoteEconomicsMismatch";
|
|
324
|
+
readonly type: "error";
|
|
325
|
+
readonly inputs: readonly [];
|
|
326
|
+
}, {
|
|
327
|
+
readonly name: "QuoteMismatch";
|
|
328
|
+
readonly type: "error";
|
|
329
|
+
readonly inputs: readonly [];
|
|
330
|
+
}, {
|
|
331
|
+
readonly name: "QuoteNotApproved";
|
|
332
|
+
readonly type: "error";
|
|
333
|
+
readonly inputs: readonly [];
|
|
334
|
+
}, {
|
|
335
|
+
readonly name: "RoyaltyTooHigh";
|
|
336
|
+
readonly type: "error";
|
|
337
|
+
readonly inputs: readonly [];
|
|
338
|
+
}, {
|
|
339
|
+
readonly name: "SeedPriceOutOfBand";
|
|
340
|
+
readonly type: "error";
|
|
341
|
+
readonly inputs: readonly [];
|
|
342
|
+
}, {
|
|
343
|
+
readonly name: "SeedSupplyTooThin";
|
|
344
|
+
readonly type: "error";
|
|
345
|
+
readonly inputs: readonly [];
|
|
346
|
+
}, {
|
|
347
|
+
readonly name: "ZeroSupply";
|
|
348
|
+
readonly type: "error";
|
|
349
|
+
readonly inputs: readonly [];
|
|
294
350
|
}];
|
|
295
351
|
export declare const AGENT_TREASURY_ABI: readonly [{
|
|
296
352
|
readonly name: "buy";
|
|
@@ -454,38 +510,6 @@ export declare const AGENT_TREASURY_ABI: readonly [{
|
|
|
454
510
|
readonly type: "uint256";
|
|
455
511
|
readonly name: "mintable";
|
|
456
512
|
}];
|
|
457
|
-
}, {
|
|
458
|
-
readonly name: "payees";
|
|
459
|
-
readonly type: "function";
|
|
460
|
-
readonly stateMutability: "view";
|
|
461
|
-
readonly inputs: readonly [];
|
|
462
|
-
readonly outputs: readonly [{
|
|
463
|
-
readonly type: "address[]";
|
|
464
|
-
}];
|
|
465
|
-
}, {
|
|
466
|
-
readonly name: "CREATOR";
|
|
467
|
-
readonly type: "function";
|
|
468
|
-
readonly stateMutability: "view";
|
|
469
|
-
readonly inputs: readonly [];
|
|
470
|
-
readonly outputs: readonly [{
|
|
471
|
-
readonly type: "address";
|
|
472
|
-
}];
|
|
473
|
-
}, {
|
|
474
|
-
readonly name: "OPERATOR";
|
|
475
|
-
readonly type: "function";
|
|
476
|
-
readonly stateMutability: "view";
|
|
477
|
-
readonly inputs: readonly [];
|
|
478
|
-
readonly outputs: readonly [{
|
|
479
|
-
readonly type: "address";
|
|
480
|
-
}];
|
|
481
|
-
}, {
|
|
482
|
-
readonly name: "QUOTE";
|
|
483
|
-
readonly type: "function";
|
|
484
|
-
readonly stateMutability: "view";
|
|
485
|
-
readonly inputs: readonly [];
|
|
486
|
-
readonly outputs: readonly [{
|
|
487
|
-
readonly type: "address";
|
|
488
|
-
}];
|
|
489
513
|
}, {
|
|
490
514
|
readonly name: "token";
|
|
491
515
|
readonly type: "function";
|
|
@@ -688,6 +712,56 @@ export declare const AGENT_TREASURY_ABI: readonly [{
|
|
|
688
712
|
readonly name: "ZeroAmount";
|
|
689
713
|
readonly type: "error";
|
|
690
714
|
readonly inputs: readonly [];
|
|
715
|
+
}, {
|
|
716
|
+
readonly name: "CurveEndReached";
|
|
717
|
+
readonly type: "error";
|
|
718
|
+
readonly inputs: readonly [];
|
|
719
|
+
}, {
|
|
720
|
+
readonly name: "Expired";
|
|
721
|
+
readonly type: "error";
|
|
722
|
+
readonly inputs: readonly [];
|
|
723
|
+
}, {
|
|
724
|
+
readonly name: "NativeInputUnsupported";
|
|
725
|
+
readonly type: "error";
|
|
726
|
+
readonly inputs: readonly [];
|
|
727
|
+
}, {
|
|
728
|
+
readonly name: "NotOurPool";
|
|
729
|
+
readonly type: "error";
|
|
730
|
+
readonly inputs: readonly [];
|
|
731
|
+
}, {
|
|
732
|
+
readonly name: "NotTradable";
|
|
733
|
+
readonly type: "error";
|
|
734
|
+
readonly inputs: readonly [];
|
|
735
|
+
}, {
|
|
736
|
+
readonly name: "SlippageExceeded";
|
|
737
|
+
readonly type: "error";
|
|
738
|
+
readonly inputs: readonly [{
|
|
739
|
+
readonly type: "uint256";
|
|
740
|
+
readonly name: "amountOut";
|
|
741
|
+
}, {
|
|
742
|
+
readonly type: "uint256";
|
|
743
|
+
readonly name: "minAmountOut";
|
|
744
|
+
}];
|
|
745
|
+
}, {
|
|
746
|
+
readonly name: "Ended";
|
|
747
|
+
readonly type: "error";
|
|
748
|
+
readonly inputs: readonly [];
|
|
749
|
+
}, {
|
|
750
|
+
readonly name: "InvalidQuantity";
|
|
751
|
+
readonly type: "error";
|
|
752
|
+
readonly inputs: readonly [];
|
|
753
|
+
}, {
|
|
754
|
+
readonly name: "NotStarted";
|
|
755
|
+
readonly type: "error";
|
|
756
|
+
readonly inputs: readonly [];
|
|
757
|
+
}, {
|
|
758
|
+
readonly name: "SupplyExceeded";
|
|
759
|
+
readonly type: "error";
|
|
760
|
+
readonly inputs: readonly [];
|
|
761
|
+
}, {
|
|
762
|
+
readonly name: "WalletCapExceeded";
|
|
763
|
+
readonly type: "error";
|
|
764
|
+
readonly inputs: readonly [];
|
|
691
765
|
}];
|
|
692
766
|
export declare const ERC20_ABI: readonly [{
|
|
693
767
|
readonly name: "approve";
|
|
@@ -728,22 +802,6 @@ export declare const ERC20_ABI: readonly [{
|
|
|
728
802
|
readonly outputs: readonly [{
|
|
729
803
|
readonly type: "uint256";
|
|
730
804
|
}];
|
|
731
|
-
}, {
|
|
732
|
-
readonly name: "decimals";
|
|
733
|
-
readonly type: "function";
|
|
734
|
-
readonly stateMutability: "view";
|
|
735
|
-
readonly inputs: readonly [];
|
|
736
|
-
readonly outputs: readonly [{
|
|
737
|
-
readonly type: "uint8";
|
|
738
|
-
}];
|
|
739
|
-
}, {
|
|
740
|
-
readonly name: "symbol";
|
|
741
|
-
readonly type: "function";
|
|
742
|
-
readonly stateMutability: "view";
|
|
743
|
-
readonly inputs: readonly [];
|
|
744
|
-
readonly outputs: readonly [{
|
|
745
|
-
readonly type: "string";
|
|
746
|
-
}];
|
|
747
805
|
}];
|
|
748
806
|
export declare const LAUNCH_FACTORY_ABI: readonly [{
|
|
749
807
|
readonly name: "launchFee";
|
package/dist/abi.js
CHANGED
|
@@ -20,6 +20,22 @@ export const AGENT_FACTORY_ABI = parseAbi([
|
|
|
20
20
|
"error TooManyPayees()",
|
|
21
21
|
"error WrongPayment()",
|
|
22
22
|
"error ZeroAddress()",
|
|
23
|
+
// A launch is validated by the launch factory and the collection, and it is their reverts a
|
|
24
|
+
// caller actually meets. Without them here a refused launch decodes to a hex blob.
|
|
25
|
+
"error EmptyURI()",
|
|
26
|
+
"error InvalidAllocation()",
|
|
27
|
+
"error InvalidLockWindow()",
|
|
28
|
+
"error InvalidTokenIdentity()",
|
|
29
|
+
"error InvalidVesting()",
|
|
30
|
+
"error InvalidWindow()",
|
|
31
|
+
"error PriceOutOfRange()",
|
|
32
|
+
"error QuoteEconomicsMismatch()",
|
|
33
|
+
"error QuoteMismatch()",
|
|
34
|
+
"error QuoteNotApproved()",
|
|
35
|
+
"error RoyaltyTooHigh()",
|
|
36
|
+
"error SeedPriceOutOfBand()",
|
|
37
|
+
"error SeedSupplyTooThin()",
|
|
38
|
+
"error ZeroSupply()",
|
|
23
39
|
]);
|
|
24
40
|
export const AGENT_TREASURY_ABI = parseAbi([
|
|
25
41
|
"function buy(uint256 amountIn,uint256 minAmountOut,uint256 deadline) returns (uint256 spent,uint256 received)",
|
|
@@ -34,10 +50,6 @@ export const AGENT_TREASURY_ABI = parseAbi([
|
|
|
34
50
|
"function freezeCollectionMetadata()",
|
|
35
51
|
"function charter() view returns (address operator,uint128 dailySpend,uint128 perCallSpend,uint128 dailySell,uint32 dailyMint,address[] payees)",
|
|
36
52
|
"function remainingToday() view returns (uint256 spend,uint256 sellable,uint256 mintable)",
|
|
37
|
-
"function payees() view returns (address[])",
|
|
38
|
-
"function CREATOR() view returns (address)",
|
|
39
|
-
"function OPERATOR() view returns (address)",
|
|
40
|
-
"function QUOTE() view returns (address)",
|
|
41
53
|
"function token() view returns (address)",
|
|
42
54
|
"function locker() view returns (address)",
|
|
43
55
|
"function collection() view returns (address)",
|
|
@@ -64,12 +76,23 @@ export const AGENT_TREASURY_ABI = parseAbi([
|
|
|
64
76
|
"error QuoteMismatch()",
|
|
65
77
|
"error UnexpectedBalance()",
|
|
66
78
|
"error ZeroAmount()",
|
|
79
|
+
// A trade reverts inside the router and a mint inside the collection, so their errors decode
|
|
80
|
+
// here or not at all. A missed floor is the likeliest failure an agent will ever hit.
|
|
81
|
+
"error CurveEndReached()",
|
|
82
|
+
"error Expired()",
|
|
83
|
+
"error NativeInputUnsupported()",
|
|
84
|
+
"error NotOurPool()",
|
|
85
|
+
"error NotTradable()",
|
|
86
|
+
"error SlippageExceeded(uint256 amountOut,uint256 minAmountOut)",
|
|
87
|
+
"error Ended()",
|
|
88
|
+
"error InvalidQuantity()",
|
|
89
|
+
"error NotStarted()",
|
|
90
|
+
"error SupplyExceeded()",
|
|
91
|
+
"error WalletCapExceeded()",
|
|
67
92
|
]);
|
|
68
93
|
export const ERC20_ABI = parseAbi([
|
|
69
94
|
"function approve(address spender,uint256 value) returns (bool)",
|
|
70
95
|
"function allowance(address owner,address spender) view returns (uint256)",
|
|
71
96
|
"function balanceOf(address account) view returns (uint256)",
|
|
72
|
-
"function decimals() view returns (uint8)",
|
|
73
|
-
"function symbol() view returns (string)",
|
|
74
97
|
]);
|
|
75
98
|
export const LAUNCH_FACTORY_ABI = parseAbi(["function launchFee() view returns (uint256)"]);
|
package/dist/agent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Account, type Address, type Hash, type Transport } from "viem";
|
|
1
|
+
import { type Account, type Address, type Hash, type PublicClient, type Transport } from "viem";
|
|
2
2
|
import { type RipplesDeployment, type RipplesNetwork } from "./chains.js";
|
|
3
3
|
import { LINKED_DEFAULTS } from "./defaults.js";
|
|
4
4
|
/**
|
|
@@ -92,6 +92,10 @@ export type RipplesAgentOptions = {
|
|
|
92
92
|
/** Overrides the network's public endpoint. */
|
|
93
93
|
rpcUrl?: string;
|
|
94
94
|
transport?: Transport;
|
|
95
|
+
/** Share a reader with the host application rather than opening a second one. */
|
|
96
|
+
publicClient?: PublicClient;
|
|
97
|
+
/** Blocks to wait before a write is treated as landed. One by default. */
|
|
98
|
+
confirmations?: number;
|
|
95
99
|
/** An existing treasury to work. `launch` fills this in when it creates one. */
|
|
96
100
|
treasury?: Address;
|
|
97
101
|
};
|
|
@@ -104,6 +108,8 @@ export type AgentClient = ReturnType<typeof createRipplesAgent>;
|
|
|
104
108
|
export declare function createRipplesAgent(options?: RipplesAgentOptions): {
|
|
105
109
|
network: RipplesNetwork;
|
|
106
110
|
deployment: RipplesDeployment;
|
|
111
|
+
/** The wallet this client signs with, where it has one. */
|
|
112
|
+
readonly address: Address | undefined;
|
|
107
113
|
readonly treasury: Address | undefined;
|
|
108
114
|
/**
|
|
109
115
|
* Create the agent, its market and its collection, in one transaction.
|
|
@@ -117,12 +123,12 @@ export declare function createRipplesAgent(options?: RipplesAgentOptions): {
|
|
|
117
123
|
/** Buy the agent's own token on its own market, into the treasury. */
|
|
118
124
|
buy(amount: string, options?: {
|
|
119
125
|
minReceived?: string;
|
|
120
|
-
|
|
126
|
+
deadlineSeconds?: number;
|
|
121
127
|
}): Promise<`0x${string}`>;
|
|
122
128
|
/** Sell it back, against the charter's daily ceiling. Refused outright when that is zero. */
|
|
123
129
|
sell(amount: string, options?: {
|
|
124
130
|
minReceived?: string;
|
|
125
|
-
|
|
131
|
+
deadlineSeconds?: number;
|
|
126
132
|
}): Promise<`0x${string}`>;
|
|
127
133
|
/** Mint from its own collection. The pieces stay with the treasury. */
|
|
128
134
|
mint(quantity: number, options?: {
|
|
@@ -140,8 +146,26 @@ export declare function createRipplesAgent(options?: RipplesAgentOptions): {
|
|
|
140
146
|
charter(): Promise<AgentCharter>;
|
|
141
147
|
/** What is left of each ceiling today. The window is the UTC day. */
|
|
142
148
|
budget(): Promise<Budget>;
|
|
143
|
-
/**
|
|
144
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Everything the agent has done, newest first.
|
|
151
|
+
*
|
|
152
|
+
* Providers cap how many blocks one `eth_getLogs` may span, and Robinhood Chain is past
|
|
153
|
+
* fifty million, so a range is asked for rather than assumed. `fromBlock` defaults to the
|
|
154
|
+
* last 50,000 blocks; pass the launch's own block for the whole history.
|
|
155
|
+
*/
|
|
156
|
+
activity(options?: {
|
|
157
|
+
limit?: number;
|
|
158
|
+
fromBlock?: bigint;
|
|
159
|
+
toBlock?: bigint | "latest";
|
|
160
|
+
}): Promise<readonly Activity[]>;
|
|
161
|
+
/**
|
|
162
|
+
* Point the collection at its artwork, and close it.
|
|
163
|
+
*
|
|
164
|
+
* The treasury owns the collection, so these are the creator's only way to attach or repair
|
|
165
|
+
* a base URI after the launch. `freezeCollectionMetadata` is one-way.
|
|
166
|
+
*/
|
|
167
|
+
setCollectionBaseUri(uri: string): Promise<`0x${string}`>;
|
|
168
|
+
freezeCollectionMetadata(): Promise<`0x${string}`>;
|
|
145
169
|
/** The launch this treasury opened. */
|
|
146
170
|
launched(): Promise<{
|
|
147
171
|
token: `0x${string}`;
|
|
@@ -151,7 +175,7 @@ export declare function createRipplesAgent(options?: RipplesAgentOptions): {
|
|
|
151
175
|
}>;
|
|
152
176
|
};
|
|
153
177
|
/** Whether this chain's factory deployed `treasury`, which is what makes its charter worth reading. */
|
|
154
|
-
export declare function
|
|
178
|
+
export declare function isRipplesAgent(treasury: Address, options?: {
|
|
155
179
|
network?: RipplesNetwork;
|
|
156
180
|
rpcUrl?: string;
|
|
157
181
|
}): Promise<boolean>;
|
package/dist/agent.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createPublicClient, createWalletClient, formatUnits, http, keccak256, parseUnits, toHex, } from "viem";
|
|
1
|
+
import { createPublicClient, createWalletClient, formatUnits, http, keccak256, parseEventLogs, parseUnits, toHex, } from "viem";
|
|
2
2
|
import { AGENT_FACTORY_ABI, AGENT_TREASURY_ABI, ERC20_ABI, LAUNCH_FACTORY_ABI } from "./abi.js";
|
|
3
3
|
import { chainOf, DEPLOYMENTS } from "./chains.js";
|
|
4
4
|
import { LINKED_DEFAULTS, LINKED_RESERVES, MAX_PAYEES, PREGEN } from "./defaults.js";
|
|
@@ -15,7 +15,7 @@ export function createRipplesAgent(options = {}) {
|
|
|
15
15
|
const record = DEPLOYMENTS[network];
|
|
16
16
|
const chain = chainOf(network);
|
|
17
17
|
const transport = options.transport ?? http(options.rpcUrl ?? record.rpcUrl);
|
|
18
|
-
const publicClient = createPublicClient({ chain, transport });
|
|
18
|
+
const publicClient = options.publicClient ?? createPublicClient({ chain, transport });
|
|
19
19
|
const wallet = options.account
|
|
20
20
|
? createWalletClient({ account: options.account, chain, transport })
|
|
21
21
|
: undefined;
|
|
@@ -39,15 +39,45 @@ export function createRipplesAgent(options = {}) {
|
|
|
39
39
|
async function send(request) {
|
|
40
40
|
const { wallet } = signer();
|
|
41
41
|
const hash = await wallet.writeContract(request);
|
|
42
|
-
|
|
42
|
+
let receipt;
|
|
43
|
+
try {
|
|
44
|
+
receipt = await publicClient.waitForTransactionReceipt({
|
|
45
|
+
hash,
|
|
46
|
+
...(options.confirmations === undefined ? {} : { confirmations: options.confirmations }),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (cause) {
|
|
50
|
+
// The transaction is in flight and the caller has nothing to name it by unless the hash
|
|
51
|
+
// comes out with the failure. Losing it after a launch means losing the treasury.
|
|
52
|
+
throw new RipplesAgentError(`Sent ${hash} and stopped waiting for it. It may still land: ${record.explorer}/tx/${hash}`, { cause });
|
|
53
|
+
}
|
|
43
54
|
if (receipt.status !== "success") {
|
|
44
|
-
|
|
55
|
+
// The estimate passed and the state moved before inclusion, which for a trade means the
|
|
56
|
+
// floor was missed. Replaying the call at that block is what turns the receipt into a
|
|
57
|
+
// named error rather than a link.
|
|
58
|
+
// Replayed at the block it failed in, which is what turns the receipt into a named error.
|
|
59
|
+
// viem decodes the revert against the same ABI, so a missed floor reads as
|
|
60
|
+
// `SlippageExceeded(amountOut, minAmountOut)` rather than as a link to a block explorer.
|
|
61
|
+
let cause;
|
|
62
|
+
try {
|
|
63
|
+
const replay = { ...request, blockNumber: receipt.blockNumber };
|
|
64
|
+
await publicClient.simulateContract(replay);
|
|
65
|
+
}
|
|
66
|
+
catch (reason) {
|
|
67
|
+
cause = reason;
|
|
68
|
+
}
|
|
69
|
+
throw new RipplesAgentError(`The transaction reverted. ${record.explorer}/tx/${hash}`, cause ? { cause } : undefined);
|
|
45
70
|
}
|
|
46
|
-
return
|
|
71
|
+
return receipt;
|
|
47
72
|
}
|
|
73
|
+
const sent = async (request) => (await send(request)).transactionHash;
|
|
48
74
|
return {
|
|
49
75
|
network,
|
|
50
76
|
deployment: record,
|
|
77
|
+
/** The wallet this client signs with, where it has one. */
|
|
78
|
+
get address() {
|
|
79
|
+
return options.account?.address;
|
|
80
|
+
},
|
|
51
81
|
get treasury() {
|
|
52
82
|
return treasury;
|
|
53
83
|
},
|
|
@@ -61,6 +91,11 @@ export function createRipplesAgent(options = {}) {
|
|
|
61
91
|
*/
|
|
62
92
|
async launch(plan) {
|
|
63
93
|
const { account } = signer();
|
|
94
|
+
// Everything the plan can get wrong is checked first, before a single read and long before
|
|
95
|
+
// the approve. An approve is a real transaction, and a launch refused after it leaves a
|
|
96
|
+
// creator out of pocket with nothing created.
|
|
97
|
+
const charter = chartered(plan.charter, quote, token);
|
|
98
|
+
planned(plan, charter, quote);
|
|
64
99
|
const runway = quote(plan.runway);
|
|
65
100
|
const fee = await publicClient.readContract({
|
|
66
101
|
address: record.tokenLaunchFactory,
|
|
@@ -70,7 +105,6 @@ export function createRipplesAgent(options = {}) {
|
|
|
70
105
|
if (runway < fee) {
|
|
71
106
|
throw new RipplesAgentError(`The runway has to cover the ${showQuote(fee)} ${record.quoteSymbol} launch fee.`);
|
|
72
107
|
}
|
|
73
|
-
const charter = chartered(plan.charter, quote, token);
|
|
74
108
|
const balance = await publicClient.readContract({
|
|
75
109
|
address: record.quote,
|
|
76
110
|
abi: ERC20_ABI,
|
|
@@ -87,7 +121,7 @@ export function createRipplesAgent(options = {}) {
|
|
|
87
121
|
args: [account.address, record.agentTreasuryFactory],
|
|
88
122
|
});
|
|
89
123
|
if (allowance < runway) {
|
|
90
|
-
await
|
|
124
|
+
await sent({
|
|
91
125
|
address: record.quote,
|
|
92
126
|
abi: ERC20_ABI,
|
|
93
127
|
functionName: "approve",
|
|
@@ -143,30 +177,48 @@ export function createRipplesAgent(options = {}) {
|
|
|
143
177
|
account,
|
|
144
178
|
chain,
|
|
145
179
|
};
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
180
|
+
// Simulated as a pre-flight only. Its return values are addresses `CREATE` will produce
|
|
181
|
+
// at the factory's current nonce, and any other launch landing first moves every one of
|
|
182
|
+
// them, so what was actually deployed is read out of the receipt instead.
|
|
183
|
+
await publicClient.simulateContract(request);
|
|
184
|
+
const receipt = await send(request);
|
|
185
|
+
const [created] = parseEventLogs({
|
|
186
|
+
abi: AGENT_FACTORY_ABI,
|
|
187
|
+
eventName: "AgentTreasuryCreated",
|
|
188
|
+
logs: receipt.logs,
|
|
189
|
+
});
|
|
190
|
+
if (!created) {
|
|
191
|
+
throw new RipplesAgentError(`The launch confirmed and its record could not be read. ${record.explorer}/tx/${receipt.transactionHash}`);
|
|
192
|
+
}
|
|
193
|
+
const [opened] = parseEventLogs({
|
|
194
|
+
abi: AGENT_TREASURY_ABI,
|
|
195
|
+
eventName: "Launched",
|
|
196
|
+
logs: receipt.logs.filter((log) => isSame(log.address, created.args.treasury)),
|
|
197
|
+
});
|
|
198
|
+
if (!opened) {
|
|
199
|
+
throw new RipplesAgentError(`The agent was created and its launch could not be read. ${record.explorer}/tx/${receipt.transactionHash}`);
|
|
200
|
+
}
|
|
201
|
+
treasury = created.args.treasury;
|
|
150
202
|
return {
|
|
151
|
-
treasury: created,
|
|
152
|
-
token:
|
|
153
|
-
market:
|
|
154
|
-
collection: collection,
|
|
155
|
-
vesting: vesting,
|
|
156
|
-
transaction,
|
|
203
|
+
treasury: created.args.treasury,
|
|
204
|
+
token: opened.args.token,
|
|
205
|
+
market: opened.args.locker,
|
|
206
|
+
collection: opened.args.collection,
|
|
207
|
+
vesting: opened.args.vesting,
|
|
208
|
+
transaction: receipt.transactionHash,
|
|
157
209
|
};
|
|
158
210
|
},
|
|
159
211
|
/** Buy the agent's own token on its own market, into the treasury. */
|
|
160
212
|
async buy(amount, options = {}) {
|
|
161
213
|
const { account } = signer();
|
|
162
|
-
return
|
|
214
|
+
return sent({
|
|
163
215
|
address: held(),
|
|
164
216
|
abi: AGENT_TREASURY_ABI,
|
|
165
217
|
functionName: "buy",
|
|
166
218
|
args: [
|
|
167
219
|
quote(amount),
|
|
168
220
|
options.minReceived ? token(options.minReceived) : 0n,
|
|
169
|
-
|
|
221
|
+
deadline(options.deadlineSeconds),
|
|
170
222
|
],
|
|
171
223
|
account,
|
|
172
224
|
chain,
|
|
@@ -175,14 +227,14 @@ export function createRipplesAgent(options = {}) {
|
|
|
175
227
|
/** Sell it back, against the charter's daily ceiling. Refused outright when that is zero. */
|
|
176
228
|
async sell(amount, options = {}) {
|
|
177
229
|
const { account } = signer();
|
|
178
|
-
return
|
|
230
|
+
return sent({
|
|
179
231
|
address: held(),
|
|
180
232
|
abi: AGENT_TREASURY_ABI,
|
|
181
233
|
functionName: "sell",
|
|
182
234
|
args: [
|
|
183
235
|
token(amount),
|
|
184
236
|
options.minReceived ? quote(options.minReceived) : 0n,
|
|
185
|
-
|
|
237
|
+
deadline(options.deadlineSeconds),
|
|
186
238
|
],
|
|
187
239
|
account,
|
|
188
240
|
chain,
|
|
@@ -191,7 +243,10 @@ export function createRipplesAgent(options = {}) {
|
|
|
191
243
|
/** Mint from its own collection. The pieces stay with the treasury. */
|
|
192
244
|
async mint(quantity, options = {}) {
|
|
193
245
|
const { account } = signer();
|
|
194
|
-
|
|
246
|
+
if (!Number.isInteger(quantity) || quantity < 1 || quantity > MAX_MINT_PER_TX) {
|
|
247
|
+
throw new RipplesAgentError(`A mint is 1 to ${MAX_MINT_PER_TX} pieces in one transaction.`);
|
|
248
|
+
}
|
|
249
|
+
return sent({
|
|
195
250
|
address: held(),
|
|
196
251
|
abi: AGENT_TREASURY_ABI,
|
|
197
252
|
functionName: "mint",
|
|
@@ -203,7 +258,7 @@ export function createRipplesAgent(options = {}) {
|
|
|
203
258
|
/** Pay one of the charter's published addresses. */
|
|
204
259
|
async pay(to, amount) {
|
|
205
260
|
const { account } = signer();
|
|
206
|
-
return
|
|
261
|
+
return sent({
|
|
207
262
|
address: held(),
|
|
208
263
|
abi: AGENT_TREASURY_ABI,
|
|
209
264
|
functionName: "pay",
|
|
@@ -215,7 +270,7 @@ export function createRipplesAgent(options = {}) {
|
|
|
215
270
|
/** Write an entry in the agent's public run log. */
|
|
216
271
|
async note(text, uri = "") {
|
|
217
272
|
const { account } = signer();
|
|
218
|
-
return
|
|
273
|
+
return sent({
|
|
219
274
|
address: held(),
|
|
220
275
|
abi: AGENT_TREASURY_ABI,
|
|
221
276
|
functionName: "note",
|
|
@@ -227,7 +282,7 @@ export function createRipplesAgent(options = {}) {
|
|
|
227
282
|
/** Take in the creator's share of every trade and the collection's share of every mint. */
|
|
228
283
|
async claim() {
|
|
229
284
|
const { account } = signer();
|
|
230
|
-
return
|
|
285
|
+
return sent({
|
|
231
286
|
address: held(),
|
|
232
287
|
abi: AGENT_TREASURY_ABI,
|
|
233
288
|
functionName: "claimFees",
|
|
@@ -239,7 +294,7 @@ export function createRipplesAgent(options = {}) {
|
|
|
239
294
|
/** Take in the token slice the agent's own mints earned it, once the market has graduated. */
|
|
240
295
|
async claimVested() {
|
|
241
296
|
const { account } = signer();
|
|
242
|
-
return
|
|
297
|
+
return sent({
|
|
243
298
|
address: held(),
|
|
244
299
|
abi: AGENT_TREASURY_ABI,
|
|
245
300
|
functionName: "claimVested",
|
|
@@ -273,9 +328,63 @@ export function createRipplesAgent(options = {}) {
|
|
|
273
328
|
});
|
|
274
329
|
return { spend: showQuote(spend), sellable: showToken(sellable), mintable: Number(mintable) };
|
|
275
330
|
},
|
|
276
|
-
/**
|
|
277
|
-
|
|
278
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Everything the agent has done, newest first.
|
|
333
|
+
*
|
|
334
|
+
* Providers cap how many blocks one `eth_getLogs` may span, and Robinhood Chain is past
|
|
335
|
+
* fifty million, so a range is asked for rather than assumed. `fromBlock` defaults to the
|
|
336
|
+
* last 50,000 blocks; pass the launch's own block for the whole history.
|
|
337
|
+
*/
|
|
338
|
+
async activity(options = {}) {
|
|
339
|
+
const toBlock = options.toBlock ?? "latest";
|
|
340
|
+
let fromBlock;
|
|
341
|
+
if (options.fromBlock === undefined) {
|
|
342
|
+
const head = await publicClient.getBlockNumber();
|
|
343
|
+
fromBlock = head > DEFAULT_LOG_SPAN ? head - DEFAULT_LOG_SPAN : 0n;
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
fromBlock = options.fromBlock;
|
|
347
|
+
}
|
|
348
|
+
return readActivity(publicClient, held(), {
|
|
349
|
+
limit: options.limit ?? 50,
|
|
350
|
+
fromBlock,
|
|
351
|
+
toBlock,
|
|
352
|
+
quoteSymbol: record.quoteSymbol,
|
|
353
|
+
tokenSymbol: "tokens",
|
|
354
|
+
showQuote,
|
|
355
|
+
showToken,
|
|
356
|
+
});
|
|
357
|
+
},
|
|
358
|
+
/**
|
|
359
|
+
* Point the collection at its artwork, and close it.
|
|
360
|
+
*
|
|
361
|
+
* The treasury owns the collection, so these are the creator's only way to attach or repair
|
|
362
|
+
* a base URI after the launch. `freezeCollectionMetadata` is one-way.
|
|
363
|
+
*/
|
|
364
|
+
async setCollectionBaseUri(uri) {
|
|
365
|
+
const { account } = signer();
|
|
366
|
+
if (!uri.endsWith("/")) {
|
|
367
|
+
throw new RipplesAgentError("A base URI has to end in a slash.");
|
|
368
|
+
}
|
|
369
|
+
return sent({
|
|
370
|
+
address: held(),
|
|
371
|
+
abi: AGENT_TREASURY_ABI,
|
|
372
|
+
functionName: "setCollectionBaseURI",
|
|
373
|
+
args: [uri],
|
|
374
|
+
account,
|
|
375
|
+
chain,
|
|
376
|
+
});
|
|
377
|
+
},
|
|
378
|
+
async freezeCollectionMetadata() {
|
|
379
|
+
const { account } = signer();
|
|
380
|
+
return sent({
|
|
381
|
+
address: held(),
|
|
382
|
+
abi: AGENT_TREASURY_ABI,
|
|
383
|
+
functionName: "freezeCollectionMetadata",
|
|
384
|
+
args: [],
|
|
385
|
+
account,
|
|
386
|
+
chain,
|
|
387
|
+
});
|
|
279
388
|
},
|
|
280
389
|
/** The launch this treasury opened. */
|
|
281
390
|
async launched() {
|
|
@@ -291,7 +400,7 @@ export function createRipplesAgent(options = {}) {
|
|
|
291
400
|
};
|
|
292
401
|
}
|
|
293
402
|
/** Whether this chain's factory deployed `treasury`, which is what makes its charter worth reading. */
|
|
294
|
-
export async function
|
|
403
|
+
export async function isRipplesAgent(treasury, options = {}) {
|
|
295
404
|
const network = options.network ?? "robinhood";
|
|
296
405
|
const record = DEPLOYMENTS[network];
|
|
297
406
|
const client = createPublicClient({
|
|
@@ -305,6 +414,98 @@ export async function readAgent(treasury, options = {}) {
|
|
|
305
414
|
args: [treasury],
|
|
306
415
|
});
|
|
307
416
|
}
|
|
417
|
+
const isSame = (left, right) => left.toLowerCase() === right.toLowerCase();
|
|
418
|
+
/// A trade's deadline is an absolute moment on chain, and callers think in durations. This takes
|
|
419
|
+
/// the seconds from now that a caller means and answers the moment the router wants.
|
|
420
|
+
const deadline = (seconds = 300) => BigInt(Math.floor(Date.now() / 1000) + seconds);
|
|
421
|
+
/** How far back `activity` looks when a caller names no range. */
|
|
422
|
+
const DEFAULT_LOG_SPAN = 50000n;
|
|
423
|
+
const MAX_UINT128 = (1n << 128n) - 1n;
|
|
424
|
+
const MAX_UINT32 = 4_294_967_295;
|
|
425
|
+
/** `Collection721.MAX_MINT_PER_TX`. */
|
|
426
|
+
const MAX_MINT_PER_TX = 20;
|
|
427
|
+
const MAX_ROYALTY_BPS = 1_000;
|
|
428
|
+
const MAX_LOGO_BYTES = 512;
|
|
429
|
+
const MAX_DESCRIPTION_BYTES = 2_048;
|
|
430
|
+
const MAX_SOCIAL_BYTES = 256;
|
|
431
|
+
const BPS = 10_000;
|
|
432
|
+
const bytes = (value) => new TextEncoder().encode(value).length;
|
|
433
|
+
/**
|
|
434
|
+
* The rules the chain holds, checked before a wallet is opened, and the two it cannot hold at
|
|
435
|
+
* all.
|
|
436
|
+
*
|
|
437
|
+
* A charter and a collection are created in one transaction and are both immutable afterwards,
|
|
438
|
+
* and nothing on chain compares them. A per-transaction limit under the mint price, or a wallet
|
|
439
|
+
* cap under the daily mint ceiling, deploys cleanly and leaves an agent that can never mint a
|
|
440
|
+
* single piece. This is the only place both halves are visible.
|
|
441
|
+
*/
|
|
442
|
+
function planned(plan, charter, quote) {
|
|
443
|
+
const { collection, token: identity } = plan;
|
|
444
|
+
const refuse = (why) => {
|
|
445
|
+
throw new RipplesAgentError(why);
|
|
446
|
+
};
|
|
447
|
+
if (!identity.image.trim())
|
|
448
|
+
refuse("A launch carries its image on chain, so `token.image` is required.");
|
|
449
|
+
if (bytes(identity.image) > MAX_LOGO_BYTES)
|
|
450
|
+
refuse(`\`token.image\` is over ${MAX_LOGO_BYTES} bytes.`);
|
|
451
|
+
if (bytes(identity.description ?? "") > MAX_DESCRIPTION_BYTES) {
|
|
452
|
+
refuse(`\`token.description\` is over ${MAX_DESCRIPTION_BYTES} bytes.`);
|
|
453
|
+
}
|
|
454
|
+
for (const [field, value] of Object.entries({
|
|
455
|
+
website: identity.website,
|
|
456
|
+
twitter: identity.twitter,
|
|
457
|
+
telegram: identity.telegram,
|
|
458
|
+
discord: identity.discord,
|
|
459
|
+
farcaster: identity.farcaster,
|
|
460
|
+
})) {
|
|
461
|
+
if (bytes(value ?? "") > MAX_SOCIAL_BYTES)
|
|
462
|
+
refuse(`\`token.${field}\` is over ${MAX_SOCIAL_BYTES} bytes.`);
|
|
463
|
+
}
|
|
464
|
+
if (collection.supply <= 0)
|
|
465
|
+
refuse("`collection.supply` has to be at least one.");
|
|
466
|
+
if ((collection.royaltyBps ?? 0) > MAX_ROYALTY_BPS) {
|
|
467
|
+
refuse(`\`collection.royaltyBps\` is at most ${MAX_ROYALTY_BPS}, which is 10%.`);
|
|
468
|
+
}
|
|
469
|
+
if (collection.endTime && collection.endTime * 1000 <= Date.now()) {
|
|
470
|
+
refuse("`collection.endTime` is in the past. Leave it out for a mint that never closes.");
|
|
471
|
+
}
|
|
472
|
+
// `Collection721` builds a token's URI by concatenating, so a base without a trailing slash
|
|
473
|
+
// produces `…/art1` rather than `…/art/1`.
|
|
474
|
+
if (!collection.baseUri.endsWith("/"))
|
|
475
|
+
refuse("`collection.baseUri` has to end in a slash.");
|
|
476
|
+
const linked = { ...LINKED_DEFAULTS, ...plan.linked };
|
|
477
|
+
if (linked.allocationBps <= 0 || linked.allocationBps >= BPS) {
|
|
478
|
+
refuse("`linked.allocationBps` is above zero and below 10000.");
|
|
479
|
+
}
|
|
480
|
+
if (linked.mintToCurveBps <= 0 || linked.mintToCurveBps > BPS) {
|
|
481
|
+
refuse("`linked.mintToCurveBps` is above zero and at most 10000.");
|
|
482
|
+
}
|
|
483
|
+
for (const [field, value] of Object.entries({
|
|
484
|
+
dailySpend: charter.dailySpend,
|
|
485
|
+
perCallSpend: charter.perCallSpend,
|
|
486
|
+
dailySell: charter.dailySell,
|
|
487
|
+
})) {
|
|
488
|
+
if (value > MAX_UINT128)
|
|
489
|
+
refuse(`\`charter.${field}\` is larger than the charter can carry.`);
|
|
490
|
+
}
|
|
491
|
+
if (charter.dailyMint > MAX_UINT32)
|
|
492
|
+
refuse("`charter.dailyMint` is larger than the charter can carry.");
|
|
493
|
+
// The two the chain never compares, and both of them are permanent.
|
|
494
|
+
const price = quote(collection.price);
|
|
495
|
+
if (charter.dailyMint > 0 && price > charter.perCallSpend) {
|
|
496
|
+
refuse("The agent could never mint: one piece costs more than `charter.perCallSpend` allows in a "
|
|
497
|
+
+ "transaction, and neither figure can be changed after the launch.");
|
|
498
|
+
}
|
|
499
|
+
if (charter.dailyMint > 0 && price * BigInt(charter.dailyMint) > charter.dailySpend) {
|
|
500
|
+
refuse("`charter.dailyMint` pieces cost more than `charter.dailySpend`, so the mint ceiling can "
|
|
501
|
+
+ "never be reached.");
|
|
502
|
+
}
|
|
503
|
+
const cap = collection.perWalletCap ?? 0;
|
|
504
|
+
if (cap > 0 && cap < charter.dailyMint) {
|
|
505
|
+
refuse("`collection.perWalletCap` counts the agent as one wallet, so it caps the agent's mints "
|
|
506
|
+
+ "for life, below its own daily ceiling.");
|
|
507
|
+
}
|
|
508
|
+
}
|
|
308
509
|
function chartered(charter, quote, token) {
|
|
309
510
|
const payees = charter.payees ?? [];
|
|
310
511
|
if (payees.length > MAX_PAYEES) {
|
|
@@ -315,9 +516,19 @@ function chartered(charter, quote, token) {
|
|
|
315
516
|
if (perCallSpend > dailySpend) {
|
|
316
517
|
throw new RipplesAgentError("`perCallSpend` cannot be above `dailySpend`.");
|
|
317
518
|
}
|
|
318
|
-
if (
|
|
519
|
+
if (perCallSpend === 0n) {
|
|
319
520
|
throw new RipplesAgentError("A per-transaction limit of zero stops every payment the agent could make, for good.");
|
|
320
521
|
}
|
|
522
|
+
if (!charter.operator || /^0x0+$/i.test(charter.operator)) {
|
|
523
|
+
throw new RipplesAgentError("`charter.operator` has to be a wallet that can sign.");
|
|
524
|
+
}
|
|
525
|
+
const seen = new Set(payees.map((payee) => payee.toLowerCase()));
|
|
526
|
+
if (seen.size !== payees.length) {
|
|
527
|
+
throw new RipplesAgentError("A charter names each payee once.");
|
|
528
|
+
}
|
|
529
|
+
if (payees.some((payee) => /^0x0+$/i.test(payee))) {
|
|
530
|
+
throw new RipplesAgentError("A payee cannot be the zero address.");
|
|
531
|
+
}
|
|
321
532
|
return {
|
|
322
533
|
operator: charter.operator,
|
|
323
534
|
dailySpend,
|
|
@@ -331,8 +542,8 @@ async function readActivity(client, treasury, units) {
|
|
|
331
542
|
const logs = await client.getLogs({
|
|
332
543
|
address: treasury,
|
|
333
544
|
events: AGENT_TREASURY_ABI.filter((entry) => entry.type === "event"),
|
|
334
|
-
fromBlock:
|
|
335
|
-
toBlock:
|
|
545
|
+
fromBlock: units.fromBlock,
|
|
546
|
+
toBlock: units.toBlock,
|
|
336
547
|
});
|
|
337
548
|
const ordered = [...logs].sort((left, right) => left.blockNumber === right.blockNumber
|
|
338
549
|
? Number((right.logIndex ?? 0n) - (left.logIndex ?? 0n))
|
|
@@ -344,8 +555,8 @@ async function readActivity(client, treasury, units) {
|
|
|
344
555
|
const args = log.args ?? {};
|
|
345
556
|
const name = log.eventName;
|
|
346
557
|
const base = { block: log.blockNumber, transaction: log.transactionHash };
|
|
347
|
-
const q = (value) => units.showQuote((value ?? 0n))
|
|
348
|
-
const t = (value) => units.showToken((value ?? 0n))
|
|
558
|
+
const q = (value) => `${units.showQuote((value ?? 0n))} ${units.quoteSymbol}`;
|
|
559
|
+
const t = (value) => `${units.showToken((value ?? 0n))} ${units.tokenSymbol}`;
|
|
349
560
|
switch (name) {
|
|
350
561
|
case "Launched":
|
|
351
562
|
out.push({ kind: "launched", ...base, detail: `Opened its launch, token ${args.token}` });
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { DEPLOYMENTS, chainOf, type RipplesDeployment, type RipplesNetwork } from "./chains.js";
|
|
2
2
|
export { LINKED_DEFAULTS, LINKED_RESERVES, MAX_PAYEES } from "./defaults.js";
|
|
3
3
|
export { AGENT_FACTORY_ABI, AGENT_TREASURY_ABI } from "./abi.js";
|
|
4
|
-
export { createRipplesAgent,
|
|
4
|
+
export { createRipplesAgent, isRipplesAgent, RipplesAgentError, type Activity, type AgentCharter, type AgentClient, type Budget, type Charter, type CollectionPlan, type LaunchPlan, type LaunchResult, type RipplesAgentOptions, type TokenPlan, } from "./agent.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { DEPLOYMENTS, chainOf } from "./chains.js";
|
|
2
2
|
export { LINKED_DEFAULTS, LINKED_RESERVES, MAX_PAYEES } from "./defaults.js";
|
|
3
3
|
export { AGENT_FACTORY_ABI, AGENT_TREASURY_ABI } from "./abi.js";
|
|
4
|
-
export { createRipplesAgent,
|
|
4
|
+
export { createRipplesAgent, isRipplesAgent, RipplesAgentError, } from "./agent.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ripplesdotrun/agent-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Launch an agent on Ripples and run it: one call to create the market, the collection and the treasury that holds the agent's money under limits nobody can raise.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ripples",
|
|
@@ -29,9 +29,10 @@
|
|
|
29
29
|
"node": ">=20"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
|
-
"build": "tsc -p tsconfig.json",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
32
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
33
|
+
"test": "node --test test/*.test.mjs",
|
|
34
|
+
"prepack": "npm run build",
|
|
35
|
+
"pretest": "npm run build"
|
|
35
36
|
},
|
|
36
37
|
"peerDependencies": {
|
|
37
38
|
"viem": "^2.21.0"
|
|
@@ -43,10 +44,8 @@
|
|
|
43
44
|
"publishConfig": {
|
|
44
45
|
"access": "public"
|
|
45
46
|
},
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
"url": "
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
"homepage": "https://ripples.run/docs#rh-agents"
|
|
47
|
+
"homepage": "https://ripples.run/docs#rh-agents",
|
|
48
|
+
"bugs": {
|
|
49
|
+
"url": "https://ripples.run/docs#rh-agents"
|
|
50
|
+
}
|
|
52
51
|
}
|