@metaplex-foundation/genesis 0.20.4 → 0.20.5
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 +90 -0
- package/dist/src/api/client.d.ts +70 -0
- package/dist/src/api/client.js +186 -0
- package/dist/src/api/client.js.map +1 -0
- package/dist/src/api/errors.d.ts +19 -0
- package/dist/src/api/errors.js +39 -0
- package/dist/src/api/errors.js.map +1 -0
- package/dist/src/api/index.d.ts +6 -0
- package/dist/src/api/index.js +22 -0
- package/dist/src/api/index.js.map +1 -0
- package/dist/src/api/payloadBuilder.d.ts +19 -0
- package/dist/src/api/payloadBuilder.js +241 -0
- package/dist/src/api/payloadBuilder.js.map +1 -0
- package/dist/src/api/transactionHelper.d.ts +20 -0
- package/dist/src/api/transactionHelper.js +45 -0
- package/dist/src/api/transactionHelper.js.map +1 -0
- package/dist/src/api/types.d.ts +166 -0
- package/dist/src/api/types.js +3 -0
- package/dist/src/api/types.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,3 +14,93 @@ A Umi-compatible JavaScript library for the project.
|
|
|
14
14
|
import { genesis } from '@metaplex-foundation/genesis';
|
|
15
15
|
umi.use(genesis());
|
|
16
16
|
```
|
|
17
|
+
|
|
18
|
+
## API Client
|
|
19
|
+
|
|
20
|
+
The API client provides three levels of control for creating and registering launches.
|
|
21
|
+
|
|
22
|
+
### Setup
|
|
23
|
+
|
|
24
|
+
All examples below assume the following shared setup:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import {
|
|
28
|
+
createAndRegisterLaunch,
|
|
29
|
+
createLaunch,
|
|
30
|
+
registerLaunch,
|
|
31
|
+
} from '@metaplex-foundation/genesis';
|
|
32
|
+
|
|
33
|
+
const config = {}; // uses default API URL; set { baseUrl: '...' } to override
|
|
34
|
+
const input = {
|
|
35
|
+
wallet: umi.identity.publicKey,
|
|
36
|
+
launchType: 'project' as const,
|
|
37
|
+
token: {
|
|
38
|
+
name: 'My Token',
|
|
39
|
+
symbol: 'MTK',
|
|
40
|
+
image: 'https://gateway.irys.xyz/...',
|
|
41
|
+
},
|
|
42
|
+
launch: {
|
|
43
|
+
launchpool: {
|
|
44
|
+
tokenAllocation: 500_000_000,
|
|
45
|
+
depositStartTime: new Date('2026-03-01T00:00:00Z'),
|
|
46
|
+
raiseGoal: 200,
|
|
47
|
+
raydiumLiquidityBps: 5000,
|
|
48
|
+
fundsRecipient: 'RecipientWallet...',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Basic — `createAndRegisterLaunch`
|
|
55
|
+
|
|
56
|
+
The simplest approach. The SDK creates the launch, signs and sends all transactions via Umi, then registers the launch — all in one call.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
const result = await createAndRegisterLaunch(umi, config, input);
|
|
60
|
+
|
|
61
|
+
console.log(`Mint: ${result.mintAddress}`);
|
|
62
|
+
console.log(`Launch: ${result.launch.link}`);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Custom transaction sender — `createAndRegisterLaunch` with `txSender`
|
|
66
|
+
|
|
67
|
+
If you need control over how transactions are signed and sent (e.g. using a custom wallet adapter), pass a `txSender` callback. The SDK still handles the create and register steps for you.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
const result = await createAndRegisterLaunch(umi, config, input, {
|
|
71
|
+
txSender: async (transactions) => {
|
|
72
|
+
const signatures: Uint8Array[] = [];
|
|
73
|
+
for (const tx of transactions) {
|
|
74
|
+
const signed = await myCustomWallet.signTransaction(tx);
|
|
75
|
+
const sig = await myCustomRpc.sendTransaction(signed);
|
|
76
|
+
signatures.push(sig);
|
|
77
|
+
}
|
|
78
|
+
return signatures;
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
console.log(`Launch: ${result.launch.link}`);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Full control — `createLaunch` + `registerLaunch`
|
|
86
|
+
|
|
87
|
+
For complete control over the transaction lifecycle, call `createLaunch` and `registerLaunch` separately. You are responsible for signing, sending, and confirming the transactions yourself.
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// Step 1: Create the launch (returns unsigned transactions)
|
|
91
|
+
const createResult = await createLaunch(umi, config, input);
|
|
92
|
+
|
|
93
|
+
// Step 2: Sign and send each transaction yourself
|
|
94
|
+
for (const tx of createResult.transactions) {
|
|
95
|
+
const signed = await umi.identity.signTransaction(tx);
|
|
96
|
+
await umi.rpc.sendTransaction(signed);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Step 3: Register the launch after transactions are confirmed on-chain
|
|
100
|
+
const registerResult = await registerLaunch(umi, config, {
|
|
101
|
+
genesisAccount: createResult.genesisAccount,
|
|
102
|
+
createLaunchInput: input,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
console.log(`Launch: ${registerResult.launch.link}`);
|
|
106
|
+
```
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Umi } from '@metaplex-foundation/umi';
|
|
2
|
+
import { CreateAndRegisterLaunchResult, CreateLaunchInput, CreateLaunchResponse, GenesisApiConfig, RegisterLaunchInput, RegisterLaunchResponse, SignAndSendOptions } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a project launch via the Genesis API.
|
|
5
|
+
*
|
|
6
|
+
* Returns deserialized Umi transactions that can be signed and sent
|
|
7
|
+
* using standard Umi methods before calling {@link registerLaunch}.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const result = await createLaunch({}, umi, {
|
|
12
|
+
* wallet: umi.identity.publicKey,
|
|
13
|
+
* token: { name: 'My Token', symbol: 'MTK', image: 'https://gateway.irys.xyz/...' },
|
|
14
|
+
* launchpool: {
|
|
15
|
+
* tokenAllocation: 500_000_000,
|
|
16
|
+
* depositStartTime: new Date('2026-03-01T00:00:00Z'),
|
|
17
|
+
* raiseGoal: 200,
|
|
18
|
+
* raydiumLiquidityBps: 5000,
|
|
19
|
+
* fundsRecipient: 'RecipientWallet...',
|
|
20
|
+
* },
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Sign and send using Umi directly
|
|
24
|
+
* for (const tx of result.transactions) {
|
|
25
|
+
* const signed = await umi.identity.signTransaction(tx);
|
|
26
|
+
* await umi.rpc.sendTransaction(signed);
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function createLaunch(umi: Umi, config: GenesisApiConfig, input: CreateLaunchInput): Promise<CreateLaunchResponse>;
|
|
31
|
+
/**
|
|
32
|
+
* Registers a launched genesis account.
|
|
33
|
+
*
|
|
34
|
+
* Call this after the create transactions have been signed and confirmed
|
|
35
|
+
* on-chain.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const registered = await registerLaunch(
|
|
40
|
+
* {},
|
|
41
|
+
* { genesisAccount: createResult.genesisAccount }
|
|
42
|
+
* );
|
|
43
|
+
* console.log(`Launch live at: ${registered.launch.link}`);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function registerLaunch(_umi: Umi, config: GenesisApiConfig, input: RegisterLaunchInput): Promise<RegisterLaunchResponse>;
|
|
47
|
+
/**
|
|
48
|
+
* High-level convenience method that orchestrates the full launch flow:
|
|
49
|
+
*
|
|
50
|
+
* 1. Creates the launch via the Genesis API (get unsigned transactions)
|
|
51
|
+
* 2. Signs and sends all transactions to the Solana RPC via Umi
|
|
52
|
+
* 3. Registers the launch
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* const result = await createAndRegisterLaunch({}, umi, {
|
|
57
|
+
* wallet: umi.identity.publicKey,
|
|
58
|
+
* token: { name: 'My Token', symbol: 'MTK', image: 'https://gateway.irys.xyz/...' },
|
|
59
|
+
* launchpool: {
|
|
60
|
+
* tokenAllocation: 500_000_000,
|
|
61
|
+
* depositStartTime: new Date('2026-03-01T00:00:00Z'),
|
|
62
|
+
* raiseGoal: 200,
|
|
63
|
+
* raydiumLiquidityBps: 5000,
|
|
64
|
+
* fundsRecipient: 'RecipientWallet...',
|
|
65
|
+
* },
|
|
66
|
+
* });
|
|
67
|
+
* console.log(`Launch live at: ${result.launch.link}`);
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare function createAndRegisterLaunch(umi: Umi, config: GenesisApiConfig, input: CreateLaunchInput, signAndSendOptions?: SignAndSendOptions): Promise<CreateAndRegisterLaunchResult>;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAndRegisterLaunch = exports.registerLaunch = exports.createLaunch = void 0;
|
|
4
|
+
const serializers_1 = require("@metaplex-foundation/umi/serializers");
|
|
5
|
+
const payloadBuilder_1 = require("./payloadBuilder");
|
|
6
|
+
const transactionHelper_1 = require("./transactionHelper");
|
|
7
|
+
const errors_1 = require("./errors");
|
|
8
|
+
const DEFAULT_BASE_URL = 'https://api.metaplex.com';
|
|
9
|
+
function resolveBaseUrl(config) {
|
|
10
|
+
return config.baseUrl ?? DEFAULT_BASE_URL;
|
|
11
|
+
}
|
|
12
|
+
function toKeyString(key) {
|
|
13
|
+
return typeof key === 'string' ? key : key.toString();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Creates a project launch via the Genesis API.
|
|
17
|
+
*
|
|
18
|
+
* Returns deserialized Umi transactions that can be signed and sent
|
|
19
|
+
* using standard Umi methods before calling {@link registerLaunch}.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const result = await createLaunch({}, umi, {
|
|
24
|
+
* wallet: umi.identity.publicKey,
|
|
25
|
+
* token: { name: 'My Token', symbol: 'MTK', image: 'https://gateway.irys.xyz/...' },
|
|
26
|
+
* launchpool: {
|
|
27
|
+
* tokenAllocation: 500_000_000,
|
|
28
|
+
* depositStartTime: new Date('2026-03-01T00:00:00Z'),
|
|
29
|
+
* raiseGoal: 200,
|
|
30
|
+
* raydiumLiquidityBps: 5000,
|
|
31
|
+
* fundsRecipient: 'RecipientWallet...',
|
|
32
|
+
* },
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* // Sign and send using Umi directly
|
|
36
|
+
* for (const tx of result.transactions) {
|
|
37
|
+
* const signed = await umi.identity.signTransaction(tx);
|
|
38
|
+
* await umi.rpc.sendTransaction(signed);
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
async function createLaunch(umi, config, input) {
|
|
43
|
+
const payload = (0, payloadBuilder_1.buildCreateLaunchPayload)(input);
|
|
44
|
+
const fetchFn = config.fetch ?? globalThis.fetch;
|
|
45
|
+
const baseUrl = resolveBaseUrl(config);
|
|
46
|
+
let response;
|
|
47
|
+
try {
|
|
48
|
+
response = await fetchFn(`${baseUrl}/v1/launches/create`, {
|
|
49
|
+
method: 'POST',
|
|
50
|
+
headers: { 'Content-Type': 'application/json' },
|
|
51
|
+
body: JSON.stringify(payload),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
throw (0, errors_1.genesisApiNetworkError)(`Network error calling createLaunch: ${err.message}`, err);
|
|
56
|
+
}
|
|
57
|
+
let body;
|
|
58
|
+
try {
|
|
59
|
+
body = await response.json();
|
|
60
|
+
}
|
|
61
|
+
catch (parseError) {
|
|
62
|
+
const rawText = await response.text().catch(() => '<unable to read body>');
|
|
63
|
+
throw (0, errors_1.genesisApiError)(`Failed to parse createLaunch response as JSON: ${parseError.message} — raw body: ${rawText}`, response.status, { rawText });
|
|
64
|
+
}
|
|
65
|
+
if (!response.ok || !body.success) {
|
|
66
|
+
throw (0, errors_1.genesisApiError)(body.error ?? `API returned status ${response.status}`, response.status, body);
|
|
67
|
+
}
|
|
68
|
+
const transactions = body.transactions.map((txBase64) => {
|
|
69
|
+
const txBytes = serializers_1.base64.serialize(txBase64);
|
|
70
|
+
return umi.transactions.deserialize(txBytes);
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
transactions,
|
|
74
|
+
blockhash: body.blockhash,
|
|
75
|
+
mintAddress: typeof body.mintAddress === 'string'
|
|
76
|
+
? body.mintAddress
|
|
77
|
+
: body.mintAddress.toString(),
|
|
78
|
+
genesisAccount: typeof body.genesisAccount === 'string'
|
|
79
|
+
? body.genesisAccount
|
|
80
|
+
: body.genesisAccount.toString(),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
exports.createLaunch = createLaunch;
|
|
84
|
+
/**
|
|
85
|
+
* Registers a launched genesis account.
|
|
86
|
+
*
|
|
87
|
+
* Call this after the create transactions have been signed and confirmed
|
|
88
|
+
* on-chain.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* const registered = await registerLaunch(
|
|
93
|
+
* {},
|
|
94
|
+
* { genesisAccount: createResult.genesisAccount }
|
|
95
|
+
* );
|
|
96
|
+
* console.log(`Launch live at: ${registered.launch.link}`);
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
async function registerLaunch(_umi, config, input) {
|
|
100
|
+
const fetchFn = config.fetch ?? globalThis.fetch;
|
|
101
|
+
const baseUrl = resolveBaseUrl(config);
|
|
102
|
+
const payload = (0, payloadBuilder_1.buildCreateLaunchPayload)(input.createLaunchInput);
|
|
103
|
+
const requestBody = {
|
|
104
|
+
genesisAccount: toKeyString(input.genesisAccount),
|
|
105
|
+
network: input.createLaunchInput.network ?? 'solana-mainnet',
|
|
106
|
+
...payload,
|
|
107
|
+
};
|
|
108
|
+
let response;
|
|
109
|
+
try {
|
|
110
|
+
response = await fetchFn(`${baseUrl}/v1/launches/register`, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
headers: { 'Content-Type': 'application/json' },
|
|
113
|
+
body: JSON.stringify(requestBody),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
throw (0, errors_1.genesisApiNetworkError)(`Network error calling registerLaunch: ${err.message}`, err);
|
|
118
|
+
}
|
|
119
|
+
let body;
|
|
120
|
+
try {
|
|
121
|
+
body = await response.json();
|
|
122
|
+
}
|
|
123
|
+
catch (parseError) {
|
|
124
|
+
const rawText = await response.text().catch(() => '<unable to read body>');
|
|
125
|
+
throw (0, errors_1.genesisApiError)(`Failed to parse registerLaunch response as JSON: ${parseError.message} — raw body: ${rawText}`, response.status, { rawText });
|
|
126
|
+
}
|
|
127
|
+
if (!response.ok || !body.success) {
|
|
128
|
+
throw (0, errors_1.genesisApiError)(body.error ?? `API returned status ${response.status}`, response.status, body);
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
existing: body.existing,
|
|
132
|
+
launch: body.launch,
|
|
133
|
+
token: body.token,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
exports.registerLaunch = registerLaunch;
|
|
137
|
+
/**
|
|
138
|
+
* High-level convenience method that orchestrates the full launch flow:
|
|
139
|
+
*
|
|
140
|
+
* 1. Creates the launch via the Genesis API (get unsigned transactions)
|
|
141
|
+
* 2. Signs and sends all transactions to the Solana RPC via Umi
|
|
142
|
+
* 3. Registers the launch
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* const result = await createAndRegisterLaunch({}, umi, {
|
|
147
|
+
* wallet: umi.identity.publicKey,
|
|
148
|
+
* token: { name: 'My Token', symbol: 'MTK', image: 'https://gateway.irys.xyz/...' },
|
|
149
|
+
* launchpool: {
|
|
150
|
+
* tokenAllocation: 500_000_000,
|
|
151
|
+
* depositStartTime: new Date('2026-03-01T00:00:00Z'),
|
|
152
|
+
* raiseGoal: 200,
|
|
153
|
+
* raydiumLiquidityBps: 5000,
|
|
154
|
+
* fundsRecipient: 'RecipientWallet...',
|
|
155
|
+
* },
|
|
156
|
+
* });
|
|
157
|
+
* console.log(`Launch live at: ${result.launch.link}`);
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
async function createAndRegisterLaunch(umi, config, input, signAndSendOptions) {
|
|
161
|
+
const createResult = await createLaunch(umi, config, input);
|
|
162
|
+
let signatures = [];
|
|
163
|
+
if (signAndSendOptions?.txSender) {
|
|
164
|
+
signatures = await signAndSendOptions.txSender(createResult.transactions);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
signatures = await (0, transactionHelper_1.signAndSendLaunchTransactions)(umi, createResult, {
|
|
168
|
+
commitment: signAndSendOptions?.commitment ?? 'confirmed',
|
|
169
|
+
preflightCommitment: signAndSendOptions?.preflightCommitment ?? 'confirmed',
|
|
170
|
+
skipPreflight: signAndSendOptions?.skipPreflight ?? false,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const registerResult = await registerLaunch(umi, config, {
|
|
174
|
+
genesisAccount: createResult.genesisAccount,
|
|
175
|
+
createLaunchInput: input,
|
|
176
|
+
});
|
|
177
|
+
return {
|
|
178
|
+
signatures,
|
|
179
|
+
mintAddress: createResult.mintAddress,
|
|
180
|
+
genesisAccount: createResult.genesisAccount,
|
|
181
|
+
launch: registerResult.launch,
|
|
182
|
+
token: registerResult.token,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
exports.createAndRegisterLaunch = createAndRegisterLaunch;
|
|
186
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface GenesisApiError extends Error {
|
|
2
|
+
readonly name: 'GenesisApiError';
|
|
3
|
+
readonly statusCode: number;
|
|
4
|
+
readonly responseBody: unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare function genesisApiError(message: string, statusCode: number, responseBody: unknown): GenesisApiError;
|
|
7
|
+
export declare function isGenesisApiError(err: unknown): err is GenesisApiError;
|
|
8
|
+
export interface GenesisApiNetworkError extends Error {
|
|
9
|
+
readonly name: 'GenesisApiNetworkError';
|
|
10
|
+
readonly cause: Error;
|
|
11
|
+
}
|
|
12
|
+
export declare function genesisApiNetworkError(message: string, cause: Error): GenesisApiNetworkError;
|
|
13
|
+
export declare function isGenesisApiNetworkError(err: unknown): err is GenesisApiNetworkError;
|
|
14
|
+
export interface GenesisValidationError extends Error {
|
|
15
|
+
readonly name: 'GenesisValidationError';
|
|
16
|
+
readonly field: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function genesisValidationError(message: string, field: string): GenesisValidationError;
|
|
19
|
+
export declare function isGenesisValidationError(err: unknown): err is GenesisValidationError;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── API Error ───────────────────────────────────────────────────────────────
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.isGenesisValidationError = exports.genesisValidationError = exports.isGenesisApiNetworkError = exports.genesisApiNetworkError = exports.isGenesisApiError = exports.genesisApiError = void 0;
|
|
5
|
+
function genesisApiError(message, statusCode, responseBody) {
|
|
6
|
+
const error = new Error(message);
|
|
7
|
+
error.name = 'GenesisApiError';
|
|
8
|
+
error.statusCode = statusCode;
|
|
9
|
+
error.responseBody = responseBody;
|
|
10
|
+
return error;
|
|
11
|
+
}
|
|
12
|
+
exports.genesisApiError = genesisApiError;
|
|
13
|
+
function isGenesisApiError(err) {
|
|
14
|
+
return err instanceof Error && err.name === 'GenesisApiError';
|
|
15
|
+
}
|
|
16
|
+
exports.isGenesisApiError = isGenesisApiError;
|
|
17
|
+
function genesisApiNetworkError(message, cause) {
|
|
18
|
+
const error = new Error(message);
|
|
19
|
+
error.name = 'GenesisApiNetworkError';
|
|
20
|
+
error.cause = cause;
|
|
21
|
+
return error;
|
|
22
|
+
}
|
|
23
|
+
exports.genesisApiNetworkError = genesisApiNetworkError;
|
|
24
|
+
function isGenesisApiNetworkError(err) {
|
|
25
|
+
return err instanceof Error && err.name === 'GenesisApiNetworkError';
|
|
26
|
+
}
|
|
27
|
+
exports.isGenesisApiNetworkError = isGenesisApiNetworkError;
|
|
28
|
+
function genesisValidationError(message, field) {
|
|
29
|
+
const error = new Error(message);
|
|
30
|
+
error.name = 'GenesisValidationError';
|
|
31
|
+
error.field = field;
|
|
32
|
+
return error;
|
|
33
|
+
}
|
|
34
|
+
exports.genesisValidationError = genesisValidationError;
|
|
35
|
+
function isGenesisValidationError(err) {
|
|
36
|
+
return err instanceof Error && err.name === 'GenesisValidationError';
|
|
37
|
+
}
|
|
38
|
+
exports.isGenesisValidationError = isGenesisValidationError;
|
|
39
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/api/errors.ts"],"names":[],"mappings":";AAAA,gFAAgF;;;AAQhF,SAAgB,eAAe,CAC7B,OAAe,EACf,UAAkB,EAClB,YAAqB;IAErB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAoB,CAAC;IACnD,KAA0B,CAAC,IAAI,GAAG,iBAAiB,CAAC;IACpD,KAAgC,CAAC,UAAU,GAAG,UAAU,CAAC;IACzD,KAAmC,CAAC,YAAY,GAAG,YAAY,CAAC;IACjE,OAAO,KAAK,CAAC;AACf,CAAC;AAVD,0CAUC;AAED,SAAgB,iBAAiB,CAAC,GAAY;IAC5C,OAAO,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,CAAC;AAChE,CAAC;AAFD,8CAEC;AASD,SAAgB,sBAAsB,CACpC,OAAe,EACf,KAAY;IAEZ,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAA2B,CAAC;IAC1D,KAA0B,CAAC,IAAI,GAAG,wBAAwB,CAAC;IAC3D,KAA0B,CAAC,KAAK,GAAG,KAAK,CAAC;IAC1C,OAAO,KAAK,CAAC;AACf,CAAC;AARD,wDAQC;AAED,SAAgB,wBAAwB,CACtC,GAAY;IAEZ,OAAO,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,wBAAwB,CAAC;AACvE,CAAC;AAJD,4DAIC;AASD,SAAgB,sBAAsB,CACpC,OAAe,EACf,KAAa;IAEb,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAA2B,CAAC;IAC1D,KAA0B,CAAC,IAAI,GAAG,wBAAwB,CAAC;IAC3D,KAA2B,CAAC,KAAK,GAAG,KAAK,CAAC;IAC3C,OAAO,KAAK,CAAC;AACf,CAAC;AARD,wDAQC;AAED,SAAgB,wBAAwB,CACtC,GAAY;IAEZ,OAAO,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,wBAAwB,CAAC;AACvE,CAAC;AAJD,4DAIC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createLaunch, registerLaunch, createAndRegisterLaunch, } from './client';
|
|
2
|
+
export { buildCreateLaunchPayload } from './payloadBuilder';
|
|
3
|
+
export { signAndSendLaunchTransactions } from './transactionHelper';
|
|
4
|
+
export type { GenesisApiError, GenesisApiNetworkError, GenesisValidationError, } from './errors';
|
|
5
|
+
export { genesisApiError, genesisApiNetworkError, genesisValidationError, isGenesisApiError, isGenesisApiNetworkError, isGenesisValidationError, } from './errors';
|
|
6
|
+
export type { GenesisApiConfig, CreateLaunchInput, CreateLaunchResponse, RegisterLaunchInput, RegisterLaunchResponse, CreateAndRegisterLaunchResult, SignAndSendOptions, SvmNetwork, TokenMetadata, LaunchpoolConfig, LockedAllocation, ExternalLinks, TimeUnit, QuoteMintInput, } from './types';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isGenesisValidationError = exports.isGenesisApiNetworkError = exports.isGenesisApiError = exports.genesisValidationError = exports.genesisApiNetworkError = exports.genesisApiError = exports.signAndSendLaunchTransactions = exports.buildCreateLaunchPayload = exports.createAndRegisterLaunch = exports.registerLaunch = exports.createLaunch = void 0;
|
|
4
|
+
// Client functions
|
|
5
|
+
var client_1 = require("./client");
|
|
6
|
+
Object.defineProperty(exports, "createLaunch", { enumerable: true, get: function () { return client_1.createLaunch; } });
|
|
7
|
+
Object.defineProperty(exports, "registerLaunch", { enumerable: true, get: function () { return client_1.registerLaunch; } });
|
|
8
|
+
Object.defineProperty(exports, "createAndRegisterLaunch", { enumerable: true, get: function () { return client_1.createAndRegisterLaunch; } });
|
|
9
|
+
// Payload builder (exported for testing and advanced use)
|
|
10
|
+
var payloadBuilder_1 = require("./payloadBuilder");
|
|
11
|
+
Object.defineProperty(exports, "buildCreateLaunchPayload", { enumerable: true, get: function () { return payloadBuilder_1.buildCreateLaunchPayload; } });
|
|
12
|
+
// Transaction helper
|
|
13
|
+
var transactionHelper_1 = require("./transactionHelper");
|
|
14
|
+
Object.defineProperty(exports, "signAndSendLaunchTransactions", { enumerable: true, get: function () { return transactionHelper_1.signAndSendLaunchTransactions; } });
|
|
15
|
+
var errors_1 = require("./errors");
|
|
16
|
+
Object.defineProperty(exports, "genesisApiError", { enumerable: true, get: function () { return errors_1.genesisApiError; } });
|
|
17
|
+
Object.defineProperty(exports, "genesisApiNetworkError", { enumerable: true, get: function () { return errors_1.genesisApiNetworkError; } });
|
|
18
|
+
Object.defineProperty(exports, "genesisValidationError", { enumerable: true, get: function () { return errors_1.genesisValidationError; } });
|
|
19
|
+
Object.defineProperty(exports, "isGenesisApiError", { enumerable: true, get: function () { return errors_1.isGenesisApiError; } });
|
|
20
|
+
Object.defineProperty(exports, "isGenesisApiNetworkError", { enumerable: true, get: function () { return errors_1.isGenesisApiNetworkError; } });
|
|
21
|
+
Object.defineProperty(exports, "isGenesisValidationError", { enumerable: true, get: function () { return errors_1.isGenesisValidationError; } });
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":";;;AAAA,mBAAmB;AACnB,mCAIkB;AAHhB,sGAAA,YAAY,OAAA;AACZ,wGAAA,cAAc,OAAA;AACd,iHAAA,uBAAuB,OAAA;AAGzB,0DAA0D;AAC1D,mDAA4D;AAAnD,0HAAA,wBAAwB,OAAA;AAEjC,qBAAqB;AACrB,yDAAoE;AAA3D,kIAAA,6BAA6B,OAAA;AAQtC,mCAOkB;AANhB,yGAAA,eAAe,OAAA;AACf,gHAAA,sBAAsB,OAAA;AACtB,gHAAA,sBAAsB,OAAA;AACtB,2GAAA,iBAAiB,OAAA;AACjB,kHAAA,wBAAwB,OAAA;AACxB,kHAAA,wBAAwB,OAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CreateLaunchInput } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Builds the API payload for `/v1/launches/create` from simplified input.
|
|
4
|
+
*/
|
|
5
|
+
export declare function buildCreateLaunchPayload(input: CreateLaunchInput): {
|
|
6
|
+
wallet: string;
|
|
7
|
+
launch: {
|
|
8
|
+
allocations: unknown[];
|
|
9
|
+
quoteMint?: string | undefined;
|
|
10
|
+
network?: "solana-devnet" | undefined;
|
|
11
|
+
publicKey: string;
|
|
12
|
+
externalLinks?: import("./types").ExternalLinks | undefined;
|
|
13
|
+
description?: string | undefined;
|
|
14
|
+
type: "project";
|
|
15
|
+
name: string;
|
|
16
|
+
symbol: string;
|
|
17
|
+
image: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCreateLaunchPayload = void 0;
|
|
4
|
+
const errors_1 = require("./errors");
|
|
5
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
6
|
+
const PROJECT_TOTAL_SUPPLY = 1000000000;
|
|
7
|
+
const DEPOSIT_DURATION_MS = 48 * 60 * 60 * 1000; // 48 hours
|
|
8
|
+
const MAX_VALID_JS_DATE_ISO = '9999-12-31T23:59:59.999Z';
|
|
9
|
+
const TOTAL_BPS = 10000;
|
|
10
|
+
const RAYDIUM_MIN_BPS = 2000;
|
|
11
|
+
const DEFAULT_UNLOCKED_BUCKET_NAME = 'Creator Allocation';
|
|
12
|
+
// ─── Quote Mint Resolution ──────────────────────────────────────────────────
|
|
13
|
+
const USDC_MINTS = {
|
|
14
|
+
'solana-mainnet': 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
|
15
|
+
'solana-devnet': '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU',
|
|
16
|
+
};
|
|
17
|
+
function resolveQuoteMint(input, network) {
|
|
18
|
+
if (!input || input === 'SOL')
|
|
19
|
+
return undefined;
|
|
20
|
+
if (input === 'USDC')
|
|
21
|
+
return USDC_MINTS[network];
|
|
22
|
+
throw (0, errors_1.genesisValidationError)(`Unsupported quote mint: '${input}'. Must be 'SOL' or 'USDC'.`, 'quoteMint');
|
|
23
|
+
}
|
|
24
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
25
|
+
function toIsoString(time) {
|
|
26
|
+
if (typeof time === 'string') {
|
|
27
|
+
const d = new Date(time);
|
|
28
|
+
if (Number.isNaN(d.getTime())) {
|
|
29
|
+
throw (0, errors_1.genesisValidationError)(`Invalid date string: ${time}`, 'time');
|
|
30
|
+
}
|
|
31
|
+
return d.toISOString();
|
|
32
|
+
}
|
|
33
|
+
if (Number.isNaN(time.getTime())) {
|
|
34
|
+
throw (0, errors_1.genesisValidationError)(`Invalid date: ${time}`, 'time');
|
|
35
|
+
}
|
|
36
|
+
return time.toISOString();
|
|
37
|
+
}
|
|
38
|
+
function toMs(time) {
|
|
39
|
+
const d = typeof time === 'string' ? new Date(time) : time;
|
|
40
|
+
return d.getTime();
|
|
41
|
+
}
|
|
42
|
+
function toKeyString(key) {
|
|
43
|
+
return typeof key === 'string' ? key : key.toString();
|
|
44
|
+
}
|
|
45
|
+
function timeAbsolute(time) {
|
|
46
|
+
return { type: 'TimeAbsolute', timestamp: toIsoString(time) };
|
|
47
|
+
}
|
|
48
|
+
// ─── Validation ─────────────────────────────────────────────────────────────
|
|
49
|
+
function validateInput(input) {
|
|
50
|
+
const { token, launch, launchType } = input;
|
|
51
|
+
if (!token.name || token.name.length < 1 || token.name.length > 32) {
|
|
52
|
+
throw (0, errors_1.genesisValidationError)('Token name must be between 1 and 32 characters', 'token.name');
|
|
53
|
+
}
|
|
54
|
+
if (!token.symbol || token.symbol.length < 1 || token.symbol.length > 10) {
|
|
55
|
+
throw (0, errors_1.genesisValidationError)('Token symbol must be between 1 and 10 characters', 'token.symbol');
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const url = new URL(token.image);
|
|
59
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
|
|
60
|
+
throw new Error();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
throw (0, errors_1.genesisValidationError)('Token image must be a valid URL', 'token.image');
|
|
65
|
+
}
|
|
66
|
+
if (token.description && token.description.length > 250) {
|
|
67
|
+
throw (0, errors_1.genesisValidationError)('Token description must be at most 250 characters', 'token.description');
|
|
68
|
+
}
|
|
69
|
+
if (launchType !== 'project') {
|
|
70
|
+
throw (0, errors_1.genesisValidationError)('Invalid launch type', 'launchType');
|
|
71
|
+
}
|
|
72
|
+
const { launchpool, lockedAllocations } = launch;
|
|
73
|
+
if (launchpool.tokenAllocation <= 0) {
|
|
74
|
+
throw (0, errors_1.genesisValidationError)('Launchpool token allocation must be greater than 0', 'launchpool.tokenAllocation');
|
|
75
|
+
}
|
|
76
|
+
if (launchpool.raiseGoal <= 0) {
|
|
77
|
+
throw (0, errors_1.genesisValidationError)('Raise goal must be greater than 0', 'launchpool.raiseGoal');
|
|
78
|
+
}
|
|
79
|
+
if (launchpool.raydiumLiquidityBps < RAYDIUM_MIN_BPS ||
|
|
80
|
+
launchpool.raydiumLiquidityBps > TOTAL_BPS) {
|
|
81
|
+
throw (0, errors_1.genesisValidationError)(`Raydium liquidity must be between ${RAYDIUM_MIN_BPS} and ${TOTAL_BPS} basis points`, 'launchpool.raydiumLiquidityBps');
|
|
82
|
+
}
|
|
83
|
+
let totalAllocated = launchpool.tokenAllocation;
|
|
84
|
+
if (lockedAllocations) {
|
|
85
|
+
for (const alloc of lockedAllocations) {
|
|
86
|
+
if (alloc.tokenAmount <= 0) {
|
|
87
|
+
throw (0, errors_1.genesisValidationError)('Locked allocation token amount must be > 0', 'lockedAllocations.tokenAmount');
|
|
88
|
+
}
|
|
89
|
+
totalAllocated += alloc.tokenAmount;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (totalAllocated > PROJECT_TOTAL_SUPPLY) {
|
|
93
|
+
throw (0, errors_1.genesisValidationError)(`Total allocated tokens (${totalAllocated}) exceeds total supply (${PROJECT_TOTAL_SUPPLY})`, 'allocations');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// ─── Payload Builder ────────────────────────────────────────────────────────
|
|
97
|
+
/**
|
|
98
|
+
* Builds the API payload for `/v1/launches/create` from simplified input.
|
|
99
|
+
*/
|
|
100
|
+
function buildCreateLaunchPayload(input) {
|
|
101
|
+
validateInput(input);
|
|
102
|
+
const { launchType, launch } = input;
|
|
103
|
+
const { launchpool, lockedAllocations } = launch;
|
|
104
|
+
const network = input.network ?? 'solana-mainnet';
|
|
105
|
+
const quoteMint = resolveQuoteMint(input.quoteMint, network);
|
|
106
|
+
const walletStr = toKeyString(input.wallet);
|
|
107
|
+
// ── Launchpool timing ─────────────────────────────────────────────────
|
|
108
|
+
const depositStartMs = toMs(launch.launchpool.depositStartTime);
|
|
109
|
+
const depositEndMs = depositStartMs + DEPOSIT_DURATION_MS;
|
|
110
|
+
const depositStartCondition = timeAbsolute(new Date(depositStartMs));
|
|
111
|
+
const depositEndCondition = timeAbsolute(new Date(depositEndMs));
|
|
112
|
+
const claimEndCondition = timeAbsolute(MAX_VALID_JS_DATE_ISO);
|
|
113
|
+
// Claim start is relative to Raydium graduation (not an absolute time).
|
|
114
|
+
// The server resolves the bucket PDA address at transaction build time.
|
|
115
|
+
const claimStartCondition = {
|
|
116
|
+
type: 'TimeRelativeToUnknownAddress',
|
|
117
|
+
bucketType: 'raydiumV2',
|
|
118
|
+
bucketIndex: 0,
|
|
119
|
+
bucketTime: 'Graduate',
|
|
120
|
+
timeOffset: 0,
|
|
121
|
+
};
|
|
122
|
+
// ── Fund flows ────────────────────────────────────────────────────────
|
|
123
|
+
const raydiumBps = launchpool.raydiumLiquidityBps;
|
|
124
|
+
const unlockedBps = TOTAL_BPS - raydiumBps;
|
|
125
|
+
const raydiumLpSupply = (launchpool.tokenAllocation * raydiumBps) / TOTAL_BPS;
|
|
126
|
+
const fundFlows = [
|
|
127
|
+
{
|
|
128
|
+
type: 'MinimumQuoteTokenThreshold',
|
|
129
|
+
recipient: walletStr,
|
|
130
|
+
claimStartCondition: depositEndCondition,
|
|
131
|
+
claimEndCondition,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
type: 'UnlockedFunds',
|
|
135
|
+
percentageBps: unlockedBps,
|
|
136
|
+
recipient: toKeyString(launchpool.fundsRecipient),
|
|
137
|
+
claimStartCondition,
|
|
138
|
+
claimEndCondition,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'RaydiumLP',
|
|
142
|
+
percentageBps: raydiumBps,
|
|
143
|
+
supply: raydiumLpSupply,
|
|
144
|
+
startCondition: depositEndCondition,
|
|
145
|
+
lpLockSchedule: {
|
|
146
|
+
startCondition: depositEndCondition,
|
|
147
|
+
cliffCondition: depositEndCondition,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
// ── Allocations ───────────────────────────────────────────────────────
|
|
152
|
+
const allocations = [];
|
|
153
|
+
// Launchpool (always first)
|
|
154
|
+
allocations.push({
|
|
155
|
+
type: 'launchpoolV2',
|
|
156
|
+
name: 'Launchpool',
|
|
157
|
+
supply: launchpool.tokenAllocation,
|
|
158
|
+
launchpoolV2: {
|
|
159
|
+
depositStartCondition,
|
|
160
|
+
depositEndCondition,
|
|
161
|
+
claimStartCondition,
|
|
162
|
+
claimEndCondition,
|
|
163
|
+
minimumQuoteTokenThreshold: launchpool.raiseGoal,
|
|
164
|
+
depositBonus: {},
|
|
165
|
+
withdrawPenalty: {},
|
|
166
|
+
fundFlows,
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
// Locked/vesting allocations (Streamflow)
|
|
170
|
+
if (lockedAllocations) {
|
|
171
|
+
for (const alloc of lockedAllocations) {
|
|
172
|
+
allocations.push({
|
|
173
|
+
type: 'lockedV2',
|
|
174
|
+
name: alloc.name,
|
|
175
|
+
supply: alloc.tokenAmount,
|
|
176
|
+
lockedV2: {
|
|
177
|
+
type: 'streamflow',
|
|
178
|
+
vesting: {
|
|
179
|
+
recipient: toKeyString(alloc.recipient),
|
|
180
|
+
startTime: toIsoString(alloc.vestingStartTime),
|
|
181
|
+
durationValue: alloc.vestingDuration.value,
|
|
182
|
+
durationUnit: alloc.vestingDuration.unit,
|
|
183
|
+
unlockSchedule: alloc.unlockSchedule,
|
|
184
|
+
cliff: alloc.cliff
|
|
185
|
+
? {
|
|
186
|
+
enabled: true,
|
|
187
|
+
durationValue: alloc.cliff.duration.value,
|
|
188
|
+
durationUnit: alloc.cliff.duration.unit,
|
|
189
|
+
...(alloc.cliff.unlockAmount !== undefined
|
|
190
|
+
? { unlockAmount: alloc.cliff.unlockAmount }
|
|
191
|
+
: {}),
|
|
192
|
+
}
|
|
193
|
+
: { enabled: false },
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Unlocked allocation for remaining supply
|
|
200
|
+
let totalAllocated = launchpool.tokenAllocation + raydiumLpSupply;
|
|
201
|
+
if (lockedAllocations) {
|
|
202
|
+
for (const alloc of lockedAllocations) {
|
|
203
|
+
totalAllocated += alloc.tokenAmount;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const remainingSupply = PROJECT_TOTAL_SUPPLY - totalAllocated;
|
|
207
|
+
if (remainingSupply > 0) {
|
|
208
|
+
allocations.push({
|
|
209
|
+
type: 'unlockedV2',
|
|
210
|
+
name: DEFAULT_UNLOCKED_BUCKET_NAME,
|
|
211
|
+
supply: remainingSupply,
|
|
212
|
+
unlockedV2: {
|
|
213
|
+
recipient: walletStr,
|
|
214
|
+
claimStartCondition,
|
|
215
|
+
claimEndCondition,
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
// ── Assemble payload ──────────────────────────────────────────────────
|
|
220
|
+
return {
|
|
221
|
+
wallet: walletStr,
|
|
222
|
+
launch: {
|
|
223
|
+
type: launchType,
|
|
224
|
+
name: input.token.name,
|
|
225
|
+
symbol: input.token.symbol,
|
|
226
|
+
image: input.token.image,
|
|
227
|
+
...(input.token.description
|
|
228
|
+
? { description: input.token.description }
|
|
229
|
+
: {}),
|
|
230
|
+
...(input.token.externalLinks
|
|
231
|
+
? { externalLinks: input.token.externalLinks }
|
|
232
|
+
: {}),
|
|
233
|
+
publicKey: walletStr,
|
|
234
|
+
...(network !== 'solana-mainnet' ? { network } : {}),
|
|
235
|
+
...(quoteMint ? { quoteMint } : {}),
|
|
236
|
+
allocations,
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
exports.buildCreateLaunchPayload = buildCreateLaunchPayload;
|
|
241
|
+
//# sourceMappingURL=payloadBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payloadBuilder.js","sourceRoot":"","sources":["../../../src/api/payloadBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Umi } from '@metaplex-foundation/umi';
|
|
2
|
+
import { CreateLaunchResponse, SignAndSendOptions } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Signs and sends the transactions returned by {@link createLaunch}.
|
|
5
|
+
*
|
|
6
|
+
* Transactions are sent **sequentially** and each is confirmed before
|
|
7
|
+
* sending the next.
|
|
8
|
+
*
|
|
9
|
+
* @param umi - Umi instance configured with the signer identity and RPC
|
|
10
|
+
* @param createResponse - The response from {@link createLaunch}
|
|
11
|
+
* @param options - Optional confirmation settings
|
|
12
|
+
* @returns Array of transaction signatures in the same order as the input transactions
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const createResult = await createLaunch(config, umi, input);
|
|
17
|
+
* const signatures = await signAndSendLaunchTransactions(umi, createResult);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function signAndSendLaunchTransactions(umi: Umi, createResponse: CreateLaunchResponse, options?: SignAndSendOptions): Promise<Uint8Array[]>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.signAndSendLaunchTransactions = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Signs and sends the transactions returned by {@link createLaunch}.
|
|
6
|
+
*
|
|
7
|
+
* Transactions are sent **sequentially** and each is confirmed before
|
|
8
|
+
* sending the next.
|
|
9
|
+
*
|
|
10
|
+
* @param umi - Umi instance configured with the signer identity and RPC
|
|
11
|
+
* @param createResponse - The response from {@link createLaunch}
|
|
12
|
+
* @param options - Optional confirmation settings
|
|
13
|
+
* @returns Array of transaction signatures in the same order as the input transactions
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const createResult = await createLaunch(config, umi, input);
|
|
18
|
+
* const signatures = await signAndSendLaunchTransactions(umi, createResult);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
async function signAndSendLaunchTransactions(umi, createResponse, options) {
|
|
22
|
+
const commitment = options?.commitment ?? 'confirmed';
|
|
23
|
+
const preflightCommitment = options?.preflightCommitment ?? 'confirmed';
|
|
24
|
+
const skipPreflight = options?.skipPreflight ?? false;
|
|
25
|
+
const signatures = [];
|
|
26
|
+
for (const transaction of createResponse.transactions) {
|
|
27
|
+
const signedTransaction = await umi.identity.signTransaction(transaction);
|
|
28
|
+
const signature = await umi.rpc.sendTransaction(signedTransaction, {
|
|
29
|
+
skipPreflight,
|
|
30
|
+
commitment,
|
|
31
|
+
preflightCommitment,
|
|
32
|
+
});
|
|
33
|
+
await umi.rpc.confirmTransaction(signature, {
|
|
34
|
+
strategy: {
|
|
35
|
+
type: 'blockhash',
|
|
36
|
+
...createResponse.blockhash,
|
|
37
|
+
},
|
|
38
|
+
commitment,
|
|
39
|
+
});
|
|
40
|
+
signatures.push(signature);
|
|
41
|
+
}
|
|
42
|
+
return signatures;
|
|
43
|
+
}
|
|
44
|
+
exports.signAndSendLaunchTransactions = signAndSendLaunchTransactions;
|
|
45
|
+
//# sourceMappingURL=transactionHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transactionHelper.js","sourceRoot":"","sources":["../../../src/api/transactionHelper.ts"],"names":[],"mappings":";;;AAKA;;;;;;;;;;;;;;;;GAgBG;AACI,KAAK,UAAU,6BAA6B,CACjD,GAAQ,EACR,cAAoC,EACpC,OAA4B;IAE5B,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,WAAW,CAAC;IACtD,MAAM,mBAAmB,GAAG,OAAO,EAAE,mBAAmB,IAAI,WAAW,CAAC;IACxE,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,KAAK,CAAC;IACtD,MAAM,UAAU,GAAiB,EAAE,CAAC;IAEpC,KAAK,MAAM,WAAW,IAAI,cAAc,CAAC,YAAY,EAAE;QACrD,MAAM,iBAAiB,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QAE1E,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,iBAAiB,EAAE;YACjE,aAAa;YACb,UAAU;YACV,mBAAmB;SACpB,CAAC,CAAC;QACH,MAAM,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,SAAS,EAAE;YAC1C,QAAQ,EAAE;gBACR,IAAI,EAAE,WAAW;gBACjB,GAAG,cAAc,CAAC,SAAS;aAC5B;YACD,UAAU;SACX,CAAC,CAAC;QAEH,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;KAC5B;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AA9BD,sEA8BC"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { BlockhashWithExpiryBlockHeight, PublicKey, RpcSendTransactionOptions, Transaction } from '@metaplex-foundation/umi';
|
|
2
|
+
export type SvmNetwork = 'solana-mainnet' | 'solana-devnet';
|
|
3
|
+
export type TimeUnit = 'SECOND' | 'MINUTE' | 'HOUR' | 'DAY' | 'WEEK' | 'TWO_WEEKS' | 'MONTH' | 'QUARTER' | 'YEAR';
|
|
4
|
+
/**
|
|
5
|
+
* Quote mint can be a friendly name ('SOL', 'USDC') or a raw mint address.
|
|
6
|
+
* The SDK resolves friendly names to the correct mint address per network.
|
|
7
|
+
*/
|
|
8
|
+
export type QuoteMintInput = 'SOL' | 'USDC' | (string & {});
|
|
9
|
+
export type LaunchType = 'project';
|
|
10
|
+
export interface ExternalLinks {
|
|
11
|
+
/** Website URL */
|
|
12
|
+
website?: string;
|
|
13
|
+
/** Twitter/X handle (e.g. '@mytoken') or full URL */
|
|
14
|
+
twitter?: string;
|
|
15
|
+
/** Telegram handle (e.g. '@mytoken') or full URL */
|
|
16
|
+
telegram?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TokenMetadata {
|
|
19
|
+
/** Token name, 1-32 characters */
|
|
20
|
+
name: string;
|
|
21
|
+
/** Token ticker symbol, 1-10 characters */
|
|
22
|
+
symbol: string;
|
|
23
|
+
/** Token image URL hosted on Irys (must start with https://gateway.irys.xyz/) */
|
|
24
|
+
image: string;
|
|
25
|
+
/** Optional description, max 250 characters */
|
|
26
|
+
description?: string;
|
|
27
|
+
/** Optional social and web links */
|
|
28
|
+
externalLinks?: ExternalLinks;
|
|
29
|
+
}
|
|
30
|
+
export interface LaunchpoolConfig {
|
|
31
|
+
/**
|
|
32
|
+
* Number of tokens to sell via the launchpool.
|
|
33
|
+
* Must be a portion of the 1 billion total supply (e.g., 500_000_000).
|
|
34
|
+
*/
|
|
35
|
+
tokenAllocation: number;
|
|
36
|
+
/**
|
|
37
|
+
* When the deposit period opens.
|
|
38
|
+
* The deposit period lasts exactly 48 hours from this time.
|
|
39
|
+
*/
|
|
40
|
+
depositStartTime: Date | string;
|
|
41
|
+
/**
|
|
42
|
+
* Minimum amount of quote tokens to raise for the launch to succeed.
|
|
43
|
+
* Specified in whole units (e.g., 200 means 200 SOL, 25000 means 25000 USDC).
|
|
44
|
+
*/
|
|
45
|
+
raiseGoal: number;
|
|
46
|
+
/**
|
|
47
|
+
* Percentage of raised funds allocated to Raydium LP, in basis points.
|
|
48
|
+
* Minimum 2000 (20%), maximum 10000 (100%).
|
|
49
|
+
* The remainder goes to the funds recipient as unlocked funds.
|
|
50
|
+
*/
|
|
51
|
+
raydiumLiquidityBps: number;
|
|
52
|
+
/**
|
|
53
|
+
* Wallet address that receives the unlocked portion of raised funds.
|
|
54
|
+
*/
|
|
55
|
+
fundsRecipient: PublicKey | string;
|
|
56
|
+
}
|
|
57
|
+
export interface LockedAllocation {
|
|
58
|
+
/** Human-readable name (e.g., 'Team', 'Advisors') for this vesting stream (max 64 chars) */
|
|
59
|
+
name: string;
|
|
60
|
+
/** Recipient wallet address */
|
|
61
|
+
recipient: PublicKey | string;
|
|
62
|
+
/** Total number of tokens in the vesting schedule */
|
|
63
|
+
tokenAmount: number;
|
|
64
|
+
/** When the vesting stream starts */
|
|
65
|
+
vestingStartTime: Date | string;
|
|
66
|
+
/** Duration of the full vesting period */
|
|
67
|
+
vestingDuration: {
|
|
68
|
+
value: number;
|
|
69
|
+
unit: TimeUnit;
|
|
70
|
+
};
|
|
71
|
+
/** How frequently tokens are released */
|
|
72
|
+
unlockSchedule: TimeUnit;
|
|
73
|
+
/** Optional cliff configuration */
|
|
74
|
+
cliff?: {
|
|
75
|
+
/** Duration until the cliff */
|
|
76
|
+
duration: {
|
|
77
|
+
value: number;
|
|
78
|
+
unit: TimeUnit;
|
|
79
|
+
};
|
|
80
|
+
/** Tokens released at cliff (in whole tokens). Defaults to linear vesting if not set. */
|
|
81
|
+
unlockAmount?: number;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export interface CreateLaunchInput {
|
|
85
|
+
/** The creator's wallet public key (will sign transactions) */
|
|
86
|
+
wallet: PublicKey | string;
|
|
87
|
+
/** Token metadata */
|
|
88
|
+
token: TokenMetadata;
|
|
89
|
+
/** Network, defaults to 'solana-mainnet' */
|
|
90
|
+
network?: SvmNetwork;
|
|
91
|
+
/**
|
|
92
|
+
* Quote token for the sale.
|
|
93
|
+
* Accepts 'SOL', 'USDC', or a raw mint address string.
|
|
94
|
+
* Defaults to 'SOL'.
|
|
95
|
+
*/
|
|
96
|
+
quoteMint?: QuoteMintInput;
|
|
97
|
+
launchType: LaunchType;
|
|
98
|
+
launch: ProjectLaunchInput;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Simplified input for creating a project launch.
|
|
102
|
+
*
|
|
103
|
+
*/
|
|
104
|
+
export interface ProjectLaunchInput {
|
|
105
|
+
/** Launchpool (primary sale mechanism) configuration */
|
|
106
|
+
launchpool: LaunchpoolConfig;
|
|
107
|
+
/** Optional: locked/vesting token allocations via Streamflow */
|
|
108
|
+
lockedAllocations?: LockedAllocation[];
|
|
109
|
+
}
|
|
110
|
+
export interface GenesisApiConfig {
|
|
111
|
+
/** Base URL of the Genesis API. Defaults to 'https://api.metaplex.com'. */
|
|
112
|
+
baseUrl?: string;
|
|
113
|
+
/** Custom fetch implementation. Defaults to globalThis.fetch. */
|
|
114
|
+
fetch?: typeof globalThis.fetch;
|
|
115
|
+
}
|
|
116
|
+
export interface RegisterLaunchInput {
|
|
117
|
+
/** The genesis account public key (returned by createLaunch) */
|
|
118
|
+
genesisAccount: PublicKey | string;
|
|
119
|
+
createLaunchInput: CreateLaunchInput;
|
|
120
|
+
}
|
|
121
|
+
export interface CreateLaunchResponse {
|
|
122
|
+
/** Deserialized Umi transactions ready to be signed and sent */
|
|
123
|
+
transactions: Transaction[];
|
|
124
|
+
/** Blockhash for transaction validity */
|
|
125
|
+
blockhash: BlockhashWithExpiryBlockHeight;
|
|
126
|
+
/** The mint address of the created token */
|
|
127
|
+
mintAddress: string;
|
|
128
|
+
/** The genesis account PDA address */
|
|
129
|
+
genesisAccount: string;
|
|
130
|
+
}
|
|
131
|
+
export interface RegisterLaunchResponse {
|
|
132
|
+
/** Whether this launch was already registered */
|
|
133
|
+
existing?: boolean;
|
|
134
|
+
/** Launch information */
|
|
135
|
+
launch: {
|
|
136
|
+
id: string;
|
|
137
|
+
link: string;
|
|
138
|
+
};
|
|
139
|
+
/** Token information */
|
|
140
|
+
token: {
|
|
141
|
+
id: string;
|
|
142
|
+
mintAddress: string;
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export interface CreateAndRegisterLaunchResult {
|
|
146
|
+
/** Transaction signatures from signing and sending */
|
|
147
|
+
signatures: Uint8Array[];
|
|
148
|
+
/** The mint address of the created token */
|
|
149
|
+
mintAddress: string;
|
|
150
|
+
/** The genesis account PDA address */
|
|
151
|
+
genesisAccount: string;
|
|
152
|
+
/** Launch information from registration */
|
|
153
|
+
launch: {
|
|
154
|
+
id: string;
|
|
155
|
+
link: string;
|
|
156
|
+
};
|
|
157
|
+
/** Token information from registration */
|
|
158
|
+
token: {
|
|
159
|
+
id: string;
|
|
160
|
+
mintAddress: string;
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
export interface SignAndSendOptions extends RpcSendTransactionOptions {
|
|
164
|
+
/** custom tx sender which returns the signatures of the transaction */
|
|
165
|
+
txSender?: (txs: Transaction[]) => Promise<Uint8Array[]>;
|
|
166
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/types.ts"],"names":[],"mappings":""}
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
exports.BACKEND_SIGNER = exports.FEE_WALLET = exports.SPL_TOKEN_2022_PROGRAM_ID = exports.WRAPPED_SOL_MINT = void 0;
|
|
18
18
|
const umi_1 = require("@metaplex-foundation/umi");
|
|
19
19
|
__exportStar(require("./allowlist"), exports);
|
|
20
|
+
__exportStar(require("./api"), exports);
|
|
20
21
|
__exportStar(require("./auction"), exports);
|
|
21
22
|
__exportStar(require("./bondingCurveHelpers"), exports);
|
|
22
23
|
__exportStar(require("./conditions"), exports);
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAAqD;AAErD,8CAA4B;AAC5B,4CAA0B;AAC1B,wDAAsC;AACtC,+CAA6B;AAC7B,yCAAuB;AACvB,8CAA4B;AAC5B,2CAAyB;AACzB,4CAA0B;AAC1B,2CAAyB;AACzB,4CAA0B;AAC1B,4CAA0B;AAC1B,6CAA2B;AAC3B,+CAA6B;AAEhB,QAAA,gBAAgB,GAAG,IAAA,eAAS,EACvC,6CAA6C,CAC9C,CAAC;AAEW,QAAA,yBAAyB,GAAG,IAAA,eAAS,EAChD,6CAA6C,CAC9C,CAAC;AAEW,QAAA,UAAU,GAAG,IAAA,eAAS,EACjC,8CAA8C,CAC/C,CAAC;AAEF,wDAAwD;AAC3C,QAAA,cAAc,GAAG,IAAA,eAAS,EACrC,8CAA8C,CAC/C,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,kDAAqD;AAErD,8CAA4B;AAC5B,wCAAsB;AACtB,4CAA0B;AAC1B,wDAAsC;AACtC,+CAA6B;AAC7B,yCAAuB;AACvB,8CAA4B;AAC5B,2CAAyB;AACzB,4CAA0B;AAC1B,2CAAyB;AACzB,4CAA0B;AAC1B,4CAA0B;AAC1B,6CAA2B;AAC3B,+CAA6B;AAEhB,QAAA,gBAAgB,GAAG,IAAA,eAAS,EACvC,6CAA6C,CAC9C,CAAC;AAEW,QAAA,yBAAyB,GAAG,IAAA,eAAS,EAChD,6CAA6C,CAC9C,CAAC;AAEW,QAAA,UAAU,GAAG,IAAA,eAAS,EACjC,8CAA8C,CAC/C,CAAC;AAEF,wDAAwD;AAC3C,QAAA,cAAc,GAAG,IAAA,eAAS,EACrC,8CAA8C,CAC/C,CAAC"}
|