@rhinestone/sdk 0.0.0-dev-20260914161313 → 0.0.0-dev-20260914164333
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/src/accounts/solana/address.d.ts +28 -0
- package/dist/src/accounts/solana/address.d.ts.map +1 -0
- package/dist/src/accounts/solana/address.js +105 -0
- package/dist/src/api/account.d.ts +3 -3
- package/dist/src/api/account.d.ts.map +1 -1
- package/dist/src/api/account.js +311 -12
- package/dist/src/api/accounts.d.ts.map +1 -1
- package/dist/src/api/accounts.js +35 -2
- package/dist/src/api/compose-types.d.ts +8 -0
- package/dist/src/api/compose-types.d.ts.map +1 -1
- package/dist/src/api/compose.d.ts.map +1 -1
- package/dist/src/api/compose.js +31 -4
- package/dist/src/chains/caip2.d.ts.map +1 -1
- package/dist/src/chains/caip2.js +5 -0
- package/dist/src/chains/non-evm.d.ts +12 -1
- package/dist/src/chains/non-evm.d.ts.map +1 -1
- package/dist/src/chains/non-evm.js +8 -1
- package/dist/src/clients/orchestrator/client.js +1 -1
- package/dist/src/clients/orchestrator/errors.d.ts +19 -2
- package/dist/src/clients/orchestrator/errors.d.ts.map +1 -1
- package/dist/src/clients/orchestrator/errors.js +47 -6
- package/dist/src/clients/orchestrator/mappers.d.ts.map +1 -1
- package/dist/src/clients/orchestrator/mappers.js +67 -35
- package/dist/src/clients/orchestrator/public.d.ts +26 -7
- package/dist/src/clients/orchestrator/public.d.ts.map +1 -1
- package/dist/src/clients/orchestrator/types.d.ts +4 -4
- package/dist/src/clients/orchestrator/types.d.ts.map +1 -1
- package/dist/src/config/account.d.ts +31 -17
- package/dist/src/config/account.d.ts.map +1 -1
- package/dist/src/errors/capability.d.ts +2 -2
- package/dist/src/errors/capability.d.ts.map +1 -1
- package/dist/src/errors/capability.js +4 -3
- package/dist/src/errors/execution.d.ts +11 -1
- package/dist/src/errors/execution.d.ts.map +1 -1
- package/dist/src/errors/execution.js +27 -1
- package/dist/src/errors/index.d.ts +3 -3
- package/dist/src/errors/index.d.ts.map +1 -1
- package/dist/src/errors/index.js +4 -4
- package/dist/src/index.d.ts +5 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/transactions/intents/normalize.d.ts.map +1 -1
- package/dist/src/transactions/intents/normalize.js +9 -2
- package/dist/src/transactions/intents/prepare.d.ts.map +1 -1
- package/dist/src/transactions/intents/prepare.js +10 -1
- package/dist/src/transactions/intents/solana.d.ts +61 -0
- package/dist/src/transactions/intents/solana.d.ts.map +1 -0
- package/dist/src/transactions/intents/solana.js +216 -0
- package/dist/src/transactions/intents/types.d.ts +20 -3
- package/dist/src/transactions/intents/types.d.ts.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Address } from 'viem';
|
|
2
|
+
import { type SolanaAddress } from '../../chains/non-evm.js';
|
|
3
|
+
/** Program used by classic Swig accounts on Solana. */
|
|
4
|
+
declare const SWIG_PROGRAM_ADDRESS: SolanaAddress;
|
|
5
|
+
declare const swigNamespaceBrand: unique symbol;
|
|
6
|
+
type SwigNamespace = string & {
|
|
7
|
+
readonly [swigNamespaceBrand]: true;
|
|
8
|
+
};
|
|
9
|
+
type ProgramAddress = {
|
|
10
|
+
readonly address: SolanaAddress;
|
|
11
|
+
readonly bump: number;
|
|
12
|
+
};
|
|
13
|
+
type SwigLocation = {
|
|
14
|
+
readonly namespace: SwigNamespace;
|
|
15
|
+
readonly evmAccount: Address;
|
|
16
|
+
readonly id: Uint8Array;
|
|
17
|
+
readonly swig: SolanaAddress;
|
|
18
|
+
readonly swigBump: number;
|
|
19
|
+
readonly wallet: SolanaAddress;
|
|
20
|
+
readonly walletBump: number;
|
|
21
|
+
};
|
|
22
|
+
declare function createProgramAddress(seeds: readonly Uint8Array[], programAddress: SolanaAddress): SolanaAddress;
|
|
23
|
+
declare function findProgramAddress(seeds: readonly Uint8Array[], programAddress: SolanaAddress): ProgramAddress;
|
|
24
|
+
declare function asSwigNamespace(value: string): SwigNamespace;
|
|
25
|
+
declare function locateSwig(namespace: SwigNamespace, evmAccount: Address): SwigLocation;
|
|
26
|
+
export type { ProgramAddress, SwigLocation, SwigNamespace };
|
|
27
|
+
export { SWIG_PROGRAM_ADDRESS, asSwigNamespace, createProgramAddress, findProgramAddress, locateSwig, };
|
|
28
|
+
//# sourceMappingURL=address.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../../../accounts/solana/address.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAqB,MAAM,MAAM,CAAA;AACtD,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,sBAAsB,CAAA;AAWxE,uDAAuD;AACvD,QAAA,MAAM,oBAAoB,eAEzB,CAAA;AAED,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,MAAM,CAAA;AAE/C,KAAK,aAAa,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AAErE,KAAK,cAAc,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B,CAAA;AAiCD,iBAAS,oBAAoB,CAC3B,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,cAAc,EAAE,aAAa,GAC5B,aAAa,CA0Bf;AAED,iBAAS,kBAAkB,CACzB,KAAK,EAAE,SAAS,UAAU,EAAE,EAC5B,cAAc,EAAE,aAAa,GAC5B,cAAc,CAqBhB;AAED,iBAAS,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAOrD;AAcD,iBAAS,UAAU,CACjB,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,OAAO,GAClB,YAAY,CAkBd;AAED,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,CAAA;AAC3D,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,GACX,CAAA"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ed25519 } from '@noble/curves/ed25519';
|
|
2
|
+
import { base58 } from '@scure/base';
|
|
3
|
+
import { isAddress, sha256 } from 'viem';
|
|
4
|
+
import { solanaAddress } from '../../chains/non-evm.js';
|
|
5
|
+
const textEncoder = new TextEncoder();
|
|
6
|
+
const PROGRAM_DERIVED_ADDRESS_MARKER = textEncoder.encode('ProgramDerivedAddress');
|
|
7
|
+
const SWIG_SEED = textEncoder.encode('swig');
|
|
8
|
+
const SWIG_WALLET_SEED = textEncoder.encode('swig-wallet-address');
|
|
9
|
+
const MAX_SEEDS = 16;
|
|
10
|
+
const MAX_SEED_LENGTH = 32;
|
|
11
|
+
/** Program used by classic Swig accounts on Solana. */
|
|
12
|
+
const SWIG_PROGRAM_ADDRESS = solanaAddress('swigypWHEksbC64pWKwah1WTeh9JXwx8H1rJHLdbQMB');
|
|
13
|
+
class OnCurveAddressError extends Error {
|
|
14
|
+
}
|
|
15
|
+
function concatBytes(values) {
|
|
16
|
+
const result = new Uint8Array(values.reduce((length, value) => length + value.length, 0));
|
|
17
|
+
let offset = 0;
|
|
18
|
+
for (const value of values) {
|
|
19
|
+
result.set(value, offset);
|
|
20
|
+
offset += value.length;
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
function decodeAddress(value) {
|
|
25
|
+
const bytes = base58.decode(value);
|
|
26
|
+
if (bytes.length !== 32) {
|
|
27
|
+
throw new TypeError('Invalid Solana address: expected 32 bytes');
|
|
28
|
+
}
|
|
29
|
+
return bytes;
|
|
30
|
+
}
|
|
31
|
+
function isOnCurve(bytes) {
|
|
32
|
+
try {
|
|
33
|
+
ed25519.ExtendedPoint.fromHex(bytes);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function createProgramAddress(seeds, programAddress) {
|
|
41
|
+
if (seeds.length > MAX_SEEDS) {
|
|
42
|
+
throw new TypeError(`Too many PDA seeds: expected at most ${MAX_SEEDS}`);
|
|
43
|
+
}
|
|
44
|
+
for (const seed of seeds) {
|
|
45
|
+
if (seed.length > MAX_SEED_LENGTH) {
|
|
46
|
+
throw new TypeError(`Invalid PDA seed: expected at most ${MAX_SEED_LENGTH} bytes`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const bytes = sha256(concatBytes([
|
|
50
|
+
...seeds,
|
|
51
|
+
decodeAddress(programAddress),
|
|
52
|
+
PROGRAM_DERIVED_ADDRESS_MARKER,
|
|
53
|
+
]), 'bytes');
|
|
54
|
+
if (isOnCurve(bytes)) {
|
|
55
|
+
throw new OnCurveAddressError('Invalid PDA seeds: address must fall off the curve');
|
|
56
|
+
}
|
|
57
|
+
return solanaAddress(base58.encode(bytes));
|
|
58
|
+
}
|
|
59
|
+
function findProgramAddress(seeds, programAddress) {
|
|
60
|
+
if (seeds.length >= MAX_SEEDS) {
|
|
61
|
+
throw new TypeError(`Too many PDA seeds: expected at most ${MAX_SEEDS - 1} before the bump`);
|
|
62
|
+
}
|
|
63
|
+
for (let bump = 255; bump >= 0; bump--) {
|
|
64
|
+
try {
|
|
65
|
+
return {
|
|
66
|
+
address: createProgramAddress([...seeds, Uint8Array.of(bump)], programAddress),
|
|
67
|
+
bump,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (!(error instanceof OnCurveAddressError))
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/* v8 ignore next -- exhausting every SHA-256 bump is not constructible */
|
|
76
|
+
throw new Error('Unable to find a viable program address bump');
|
|
77
|
+
}
|
|
78
|
+
function asSwigNamespace(value) {
|
|
79
|
+
if (!/^[a-z0-9-]{1,32}$/.test(value)) {
|
|
80
|
+
throw new TypeError(`Invalid Swig namespace "${value}": expected 1-32 chars of [a-z0-9-]`);
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
function swigId(namespace, evmAccount) {
|
|
85
|
+
if (!isAddress(evmAccount, { strict: false })) {
|
|
86
|
+
throw new TypeError(`Invalid EVM account address: ${evmAccount}`);
|
|
87
|
+
}
|
|
88
|
+
return sha256(textEncoder.encode(`rhinestone:swig:v1:${namespace}:${evmAccount.toLowerCase()}`), 'bytes');
|
|
89
|
+
}
|
|
90
|
+
function locateSwig(namespace, evmAccount) {
|
|
91
|
+
const normalizedAccount = evmAccount.toLowerCase();
|
|
92
|
+
const id = swigId(namespace, normalizedAccount);
|
|
93
|
+
const swig = findProgramAddress([SWIG_SEED, id], SWIG_PROGRAM_ADDRESS);
|
|
94
|
+
const wallet = findProgramAddress([SWIG_WALLET_SEED, decodeAddress(swig.address)], SWIG_PROGRAM_ADDRESS);
|
|
95
|
+
return {
|
|
96
|
+
namespace,
|
|
97
|
+
evmAccount: normalizedAccount,
|
|
98
|
+
id,
|
|
99
|
+
swig: swig.address,
|
|
100
|
+
swigBump: swig.bump,
|
|
101
|
+
wallet: wallet.address,
|
|
102
|
+
walletBump: wallet.bump,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export { SWIG_PROGRAM_ADDRESS, asSwigNamespace, createProgramAddress, findProgramAddress, locateSwig, };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Address, Chain, HashTypedDataParameters, Hex, SignableMessage, SignedAuthorizationList, TypedData, TypedDataDefinition } from 'viem';
|
|
2
2
|
import type { UserOperationReceipt } from 'viem/account-abstraction';
|
|
3
3
|
import { type DestinationChain, type SolanaAddress } from '../chains/non-evm.js';
|
|
4
|
-
import type { HyperCoreAction, OriginSignature, Portfolio, SignData } from '../clients/orchestrator/public.js';
|
|
4
|
+
import type { HyperCoreAction, OriginSignature, OriginSignData, Portfolio, SignData } from '../clients/orchestrator/public.js';
|
|
5
5
|
import type { AccountTransaction, EvmAccountConfig, RhinestoneAccountConfig, Session, SignerSet, SolanaManagedAccountConfig, Transaction, UserOperationTransaction } from '../config/account.js';
|
|
6
6
|
import type { LegacyAccountConfig } from '../config/legacy.js';
|
|
7
7
|
import type { AccountInvocationContext } from '../config/resolved.js';
|
|
@@ -66,8 +66,8 @@ export interface ManagedTransactionAccount<_C extends RhinestoneAccountConfig =
|
|
|
66
66
|
* @see {@link prepareTransaction} to prepare the transaction data for signing
|
|
67
67
|
*/
|
|
68
68
|
getTransactionMessages(preparedTransaction: PreparedTransactionData, options?: QuoteSelection): {
|
|
69
|
-
origin:
|
|
70
|
-
destination
|
|
69
|
+
origin: OriginSignData[];
|
|
70
|
+
destination?: TypedDataDefinition;
|
|
71
71
|
targetExecution?: TypedDataDefinition;
|
|
72
72
|
};
|
|
73
73
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../api/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../api/account.ts"],"names":[],"mappings":"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"}
|
package/dist/src/api/account.js
CHANGED
|
@@ -1,27 +1,43 @@
|
|
|
1
|
+
import { asSwigNamespace, locateSwig } from '../accounts/solana/address.js';
|
|
1
2
|
import { formatCaip2, parseCaip2, toEvmChainReference } from '../chains/caip2.js';
|
|
2
3
|
import { getChainById, getChainReference } from '../chains/catalog.js';
|
|
3
4
|
import { solanaAddress, } from '../chains/non-evm.js';
|
|
4
5
|
import { normalizeTokenAddress, validateTokenAddresses } from '../chains/tokens.js';
|
|
5
6
|
import { createStaticAccountRuntime } from '../config/account-runtime.js';
|
|
6
7
|
import { materializeAccountInvocationContext, resolveAccountConfig, } from '../config/resolve.js';
|
|
7
|
-
import { AccountVmNotConfiguredError, UnsupportedAccountCapabilityError, } from '../errors/capability.js';
|
|
8
|
-
import { IndependentSigningNotSupportedError, MismatchedOwnerSignaturesError, QuoteNotInPreparedTransactionError, } from '../errors/execution.js';
|
|
8
|
+
import { AccountVmNotConfiguredError, ManagedSolanaAccountNotSupportedError, UnsupportedAccountCapabilityError, } from '../errors/capability.js';
|
|
9
|
+
import { IndependentSigningNotSupportedError, InvalidSolanaTransactionArtifactError, MismatchedOwnerSignaturesError, QuoteNotInPreparedTransactionError, } from '../errors/execution.js';
|
|
9
10
|
import { resolveHyperCoreAction } from '../hypercore/resolve.js';
|
|
10
11
|
import { ecdsaSignerId, webauthnSignerId, } from '../modules/validators/signer-id.js';
|
|
11
12
|
import { projectIntentAccount, projectIntentRecipient, } from '../transactions/intents/account.js';
|
|
12
13
|
import { projectCompatibleIntentInput, projectCompatibleQuote, } from '../transactions/intents/compatibility.js';
|
|
13
14
|
import { normalizeIntentQuote } from '../transactions/intents/normalize.js';
|
|
15
|
+
import { solanaChainId, } from '../transactions/intents/solana.js';
|
|
14
16
|
import { adaptSignerSelection, adaptUserOperationSignerSelection, } from './signer-selection.js';
|
|
17
|
+
function cloneArtifactValue(value) {
|
|
18
|
+
if (Array.isArray(value)) {
|
|
19
|
+
return value.map(cloneArtifactValue);
|
|
20
|
+
}
|
|
21
|
+
if (value && typeof value === 'object') {
|
|
22
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
23
|
+
key,
|
|
24
|
+
cloneArtifactValue(item),
|
|
25
|
+
]));
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
15
29
|
function toPublicQuote(quote) {
|
|
16
30
|
const compatible = projectCompatibleQuote(quote);
|
|
17
|
-
return {
|
|
31
|
+
return cloneArtifactValue({
|
|
18
32
|
intentId: compatible.intentId,
|
|
19
33
|
expiresAt: compatible.expiresAt,
|
|
20
34
|
estimatedFillTime: compatible.estimatedFillTime,
|
|
21
35
|
settlementLayer: compatible.settlementLayer,
|
|
22
36
|
signData: {
|
|
23
37
|
origin: [...compatible.signData.origin],
|
|
24
|
-
|
|
38
|
+
...(compatible.signData.destination
|
|
39
|
+
? { destination: compatible.signData.destination }
|
|
40
|
+
: {}),
|
|
25
41
|
...(compatible.signData.targetExecution
|
|
26
42
|
? { targetExecution: compatible.signData.targetExecution }
|
|
27
43
|
: {}),
|
|
@@ -31,7 +47,7 @@ function toPublicQuote(quote) {
|
|
|
31
47
|
? { tokenRequirements: compatible.tokenRequirements }
|
|
32
48
|
: {}),
|
|
33
49
|
...(compatible.bridgeFill ? { bridgeFill: compatible.bridgeFill } : {}),
|
|
34
|
-
};
|
|
50
|
+
});
|
|
35
51
|
}
|
|
36
52
|
function toPreparedTransactionData(prepared, transaction, cache) {
|
|
37
53
|
const data = {
|
|
@@ -46,6 +62,32 @@ function toPreparedTransactionData(prepared, transaction, cache) {
|
|
|
46
62
|
cache.set(data, prepared);
|
|
47
63
|
return data;
|
|
48
64
|
}
|
|
65
|
+
function toPreparedSolanaTransactionData(prepared, transaction) {
|
|
66
|
+
const input = prepared.input;
|
|
67
|
+
return {
|
|
68
|
+
quotes: {
|
|
69
|
+
traceId: prepared.traceId,
|
|
70
|
+
best: toPublicQuote(prepared.quote),
|
|
71
|
+
all: prepared.quotes.map(toPublicQuote),
|
|
72
|
+
},
|
|
73
|
+
execution: {
|
|
74
|
+
kind: 'solana',
|
|
75
|
+
namespace: input.namespace,
|
|
76
|
+
endpoint: input.endpoint,
|
|
77
|
+
chain: solanaChainId(input.chain),
|
|
78
|
+
caip2: input.chain.caip2,
|
|
79
|
+
accountAddress: input.accountAddress,
|
|
80
|
+
accountType: input.accountType,
|
|
81
|
+
authority: input.authority,
|
|
82
|
+
swigAddress: input.swigAddress,
|
|
83
|
+
walletAddress: input.walletAddress,
|
|
84
|
+
recipient: input.recipient,
|
|
85
|
+
mint: input.mint,
|
|
86
|
+
},
|
|
87
|
+
intentInput: projectCompatibleIntentInput(prepared.request),
|
|
88
|
+
transaction,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
49
91
|
function selectedPublicQuote(prepared, intentId) {
|
|
50
92
|
if (!intentId)
|
|
51
93
|
return prepared.quotes.best;
|
|
@@ -78,8 +120,12 @@ function toSignedTransactionData(prepared, signed, cache) {
|
|
|
78
120
|
...prepared,
|
|
79
121
|
quote: toPublicQuote(signed.prepared.quote),
|
|
80
122
|
originSignatures: signed.originSignatures,
|
|
81
|
-
|
|
82
|
-
|
|
123
|
+
...(signed.destinationSignature
|
|
124
|
+
? { destinationSignature: signed.destinationSignature }
|
|
125
|
+
: {}),
|
|
126
|
+
...(signed.targetSignature
|
|
127
|
+
? { targetExecutionSignature: signed.targetSignature }
|
|
128
|
+
: {}),
|
|
83
129
|
};
|
|
84
130
|
cache.set(data, signed);
|
|
85
131
|
return data;
|
|
@@ -96,6 +142,95 @@ export function createAccountFacade(compatibilityConfig, publicConfig, compositi
|
|
|
96
142
|
const signedIntents = new WeakMap();
|
|
97
143
|
const context = (method) => materializeAccountInvocationContext(composition.config, compatibilityConfig, method);
|
|
98
144
|
const workflowsFor = (ctx) => composition.createAccount(ctx).workflows;
|
|
145
|
+
const hasManagedSolana = Boolean(publicConfig.solana && 'owner' in publicConfig.solana);
|
|
146
|
+
const capturedSolanaContext = hasManagedSolana
|
|
147
|
+
? context('get-address')
|
|
148
|
+
: undefined;
|
|
149
|
+
const capturedSolanaIdentity = capturedSolanaContext
|
|
150
|
+
? workflowsFor(capturedSolanaContext).getAddress(capturedSolanaContext, referenceChain())
|
|
151
|
+
: undefined;
|
|
152
|
+
const capturedSolanaEndpoint = capturedSolanaContext?.sdk.orchestratorUrl;
|
|
153
|
+
const capturedSolanaAccountType = capturedSolanaContext
|
|
154
|
+
? capturedSolanaContext.account.account.kind === 'eoa'
|
|
155
|
+
? 'EOA'
|
|
156
|
+
: capturedSolanaContext.account.account.kind === 'hca'
|
|
157
|
+
? 'GENERIC'
|
|
158
|
+
: 'ERC7579'
|
|
159
|
+
: undefined;
|
|
160
|
+
const solanaOwner = () => {
|
|
161
|
+
const branch = publicConfig.solana;
|
|
162
|
+
if (!branch || !('owner' in branch) || !branch.owner) {
|
|
163
|
+
throw new UnsupportedAccountCapabilityError('A managed Solana source is not configured on this account.', { vm: 'solana' });
|
|
164
|
+
}
|
|
165
|
+
return branch.owner.account;
|
|
166
|
+
};
|
|
167
|
+
const solanaTransfer = (ctx, transaction) => {
|
|
168
|
+
assertSupportedTransaction(transaction, publicConfig);
|
|
169
|
+
if (ctx.sdk.environment !== 'development' ||
|
|
170
|
+
ctx.sdk.orchestratorUrl !== capturedSolanaEndpoint) {
|
|
171
|
+
throw new ManagedSolanaAccountNotSupportedError('Managed Solana execution remains bound to the development environment and endpoint captured when the account was created.');
|
|
172
|
+
}
|
|
173
|
+
if (!isSolanaOrigin(transaction)) {
|
|
174
|
+
throw new InvalidSolanaTransactionArtifactError('the transaction is not a same-chain Solana transfer');
|
|
175
|
+
}
|
|
176
|
+
const request = transaction.tokenRequests[0];
|
|
177
|
+
const accountAddress = capturedSolanaIdentity;
|
|
178
|
+
if (!accountAddress || !capturedSolanaAccountType) {
|
|
179
|
+
throw new UnsupportedAccountCapabilityError('A managed Solana source is not configured on this account.', { vm: 'solana' });
|
|
180
|
+
}
|
|
181
|
+
const location = locateSwig(asSwigNamespace('dev-v1'), accountAddress);
|
|
182
|
+
return {
|
|
183
|
+
chain: transaction.chain,
|
|
184
|
+
mint: request.address,
|
|
185
|
+
...(request.amount === undefined ? {} : { amount: request.amount }),
|
|
186
|
+
recipient: transaction.recipient,
|
|
187
|
+
accountAddress,
|
|
188
|
+
accountType: capturedSolanaAccountType,
|
|
189
|
+
authority: solanaOwner().address,
|
|
190
|
+
walletAddress: location.wallet,
|
|
191
|
+
swigAddress: location.swig,
|
|
192
|
+
namespace: 'dev-v1',
|
|
193
|
+
endpoint: ctx.sdk.orchestratorUrl,
|
|
194
|
+
...(transaction.appFees ? { appFees: transaction.appFees } : {}),
|
|
195
|
+
...(transaction.protocolFees
|
|
196
|
+
? { protocolFees: transaction.protocolFees }
|
|
197
|
+
: {}),
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
const assertSolanaMetadata = (actual, expected) => {
|
|
201
|
+
const expectedMetadata = {
|
|
202
|
+
kind: 'solana',
|
|
203
|
+
namespace: expected.namespace,
|
|
204
|
+
endpoint: expected.endpoint,
|
|
205
|
+
chain: solanaChainId(expected.chain),
|
|
206
|
+
caip2: expected.chain.caip2,
|
|
207
|
+
accountAddress: expected.accountAddress,
|
|
208
|
+
accountType: expected.accountType,
|
|
209
|
+
authority: expected.authority,
|
|
210
|
+
swigAddress: expected.swigAddress,
|
|
211
|
+
walletAddress: expected.walletAddress,
|
|
212
|
+
recipient: expected.recipient,
|
|
213
|
+
mint: expected.mint,
|
|
214
|
+
};
|
|
215
|
+
const expectedEntries = Object.entries(expectedMetadata);
|
|
216
|
+
if (!actual ||
|
|
217
|
+
Object.keys(actual).length !== expectedEntries.length ||
|
|
218
|
+
expectedEntries.some(([key, value]) => actual[key] !== value)) {
|
|
219
|
+
throw new InvalidSolanaTransactionArtifactError('the execution binding does not match this account, environment, chain, recipient, or mint');
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const resolveSolanaPrepared = (ctx, prepared, intentId, explicitQuote) => {
|
|
223
|
+
const transfer = solanaTransfer(ctx, prepared.transaction);
|
|
224
|
+
assertSolanaMetadata(prepared.execution, transfer);
|
|
225
|
+
const quote = explicitQuote ?? selectedPublicQuote(prepared, intentId);
|
|
226
|
+
return workflowsFor(ctx).reconstructSolanaIntent({
|
|
227
|
+
traceId: prepared.quotes.traceId,
|
|
228
|
+
transfer,
|
|
229
|
+
intentInput: prepared.intentInput,
|
|
230
|
+
quote: normalizeIntentQuote(quote),
|
|
231
|
+
quotes: prepared.quotes.all.map((candidate) => normalizeIntentQuote(candidate)),
|
|
232
|
+
});
|
|
233
|
+
};
|
|
99
234
|
const resolvePrepared = (ctx, prepared, intentId) => {
|
|
100
235
|
assertSupportedTransaction(prepared.transaction, publicConfig);
|
|
101
236
|
assertSupportedSignData(selectedPublicQuote(prepared, intentId).signData);
|
|
@@ -133,7 +268,22 @@ export function createAccountFacade(compatibilityConfig, publicConfig, compositi
|
|
|
133
268
|
},
|
|
134
269
|
async prepareTransaction(transaction) {
|
|
135
270
|
const ctx = context('prepare-intent');
|
|
136
|
-
const
|
|
271
|
+
const initiallyNormalized = normalizeTransaction(transaction, publicConfig);
|
|
272
|
+
const normalized = 'targetChain' in initiallyNormalized &&
|
|
273
|
+
initiallyNormalized.targetChain !== undefined &&
|
|
274
|
+
'kind' in initiallyNormalized.targetChain &&
|
|
275
|
+
initiallyNormalized.targetChain.kind === 'svm' &&
|
|
276
|
+
initiallyNormalized.recipient === undefined &&
|
|
277
|
+
capturedSolanaIdentity
|
|
278
|
+
? Object.freeze({
|
|
279
|
+
...initiallyNormalized,
|
|
280
|
+
recipient: locateSwig(asSwigNamespace('dev-v1'), capturedSolanaIdentity).wallet,
|
|
281
|
+
})
|
|
282
|
+
: initiallyNormalized;
|
|
283
|
+
if (isSolanaOrigin(normalized)) {
|
|
284
|
+
const prepared = await workflowsFor(ctx).prepareSolanaIntent(solanaTransfer(ctx, normalized));
|
|
285
|
+
return toPreparedSolanaTransactionData(prepared, normalized);
|
|
286
|
+
}
|
|
137
287
|
// Before the quote, not after: the quote's `signData` registers an agent
|
|
138
288
|
// derived from the action's bytes, so the action has to be concrete here.
|
|
139
289
|
const hyperCoreAction = await resolveHyperCoreAction({
|
|
@@ -155,10 +305,18 @@ export function createAccountFacade(compatibilityConfig, publicConfig, compositi
|
|
|
155
305
|
getTransactionMessages(preparedTransaction, options) {
|
|
156
306
|
assertSupportedTransaction(preparedTransaction.transaction, publicConfig);
|
|
157
307
|
const quote = selectedPublicQuote(preparedTransaction, options?.intentId);
|
|
158
|
-
|
|
308
|
+
if (!isSolanaOrigin(preparedTransaction.transaction)) {
|
|
309
|
+
assertSupportedSignData(quote.signData);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
const ctx = context('get-intent-messages');
|
|
313
|
+
resolveSolanaPrepared(ctx, preparedTransaction, options?.intentId);
|
|
314
|
+
}
|
|
159
315
|
return {
|
|
160
316
|
origin: [...quote.signData.origin],
|
|
161
|
-
|
|
317
|
+
...(quote.signData.destination
|
|
318
|
+
? { destination: quote.signData.destination }
|
|
319
|
+
: {}),
|
|
162
320
|
...(quote.signData.targetExecution
|
|
163
321
|
? { targetExecution: quote.signData.targetExecution }
|
|
164
322
|
: {}),
|
|
@@ -167,6 +325,23 @@ export function createAccountFacade(compatibilityConfig, publicConfig, compositi
|
|
|
167
325
|
signTransaction: (async (preparedTransaction, options) => {
|
|
168
326
|
const ctx = context('sign-intent');
|
|
169
327
|
const workflows = workflowsFor(ctx);
|
|
328
|
+
if (isSolanaOrigin(preparedTransaction.transaction)) {
|
|
329
|
+
if (options && 'owner' in options) {
|
|
330
|
+
throw new IndependentSigningNotSupportedError({
|
|
331
|
+
context: { vm: 'solana' },
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
const prepared = resolveSolanaPrepared(ctx, preparedTransaction, options?.intentId);
|
|
335
|
+
const signed = await workflows.signSolanaIntent({
|
|
336
|
+
prepared,
|
|
337
|
+
owner: solanaOwner(),
|
|
338
|
+
});
|
|
339
|
+
return {
|
|
340
|
+
...preparedTransaction,
|
|
341
|
+
quote: toPublicQuote(signed.prepared.quote),
|
|
342
|
+
originSignatures: [signed.signature],
|
|
343
|
+
};
|
|
344
|
+
}
|
|
170
345
|
if (options && 'owner' in options) {
|
|
171
346
|
// Independent owner signing is unsupported for smart-session intents;
|
|
172
347
|
// reject before resolving sessions (which would issue an RPC read),
|
|
@@ -188,6 +363,11 @@ export function createAccountFacade(compatibilityConfig, publicConfig, compositi
|
|
|
188
363
|
return toSignedTransactionData(preparedTransaction, intent, signedIntents);
|
|
189
364
|
}),
|
|
190
365
|
async assembleTransaction(preparedTransaction, signatures) {
|
|
366
|
+
if (isSolanaOrigin(preparedTransaction.transaction)) {
|
|
367
|
+
throw new IndependentSigningNotSupportedError({
|
|
368
|
+
context: { vm: 'solana' },
|
|
369
|
+
});
|
|
370
|
+
}
|
|
191
371
|
const ctx = context('assemble-intent');
|
|
192
372
|
const workflows = workflowsFor(ctx);
|
|
193
373
|
const intentIds = [...new Set(signatures.map(({ intentId }) => intentId))];
|
|
@@ -200,6 +380,9 @@ export function createAccountFacade(compatibilityConfig, publicConfig, compositi
|
|
|
200
380
|
},
|
|
201
381
|
async signAuthorizations(preparedTransaction) {
|
|
202
382
|
assertSupportedTransaction(preparedTransaction.transaction, publicConfig);
|
|
383
|
+
if (isSolanaOrigin(preparedTransaction.transaction)) {
|
|
384
|
+
throw new UnsupportedAccountCapabilityError('EIP-7702 authorizations are unavailable for Solana-origin transactions.', { vm: 'solana' });
|
|
385
|
+
}
|
|
203
386
|
const ctx = context('sign-authorizations');
|
|
204
387
|
const intentInput = adaptTransaction(ctx, preparedTransaction.transaction);
|
|
205
388
|
const chains = authorizationChains(intentInput);
|
|
@@ -257,9 +440,34 @@ export function createAccountFacade(compatibilityConfig, publicConfig, compositi
|
|
|
257
440
|
},
|
|
258
441
|
async submitTransaction(signedTransaction, options) {
|
|
259
442
|
assertSupportedTransaction(signedTransaction.transaction, publicConfig);
|
|
260
|
-
assertSupportedSignData(signedTransaction.quote.signData);
|
|
261
443
|
const ctx = context('submit-intent');
|
|
262
444
|
const workflows = workflowsFor(ctx);
|
|
445
|
+
if (isSolanaOrigin(signedTransaction.transaction)) {
|
|
446
|
+
if (options && Object.keys(options).length > 0) {
|
|
447
|
+
throw new UnsupportedAccountCapabilityError('Solana submission does not accept EVM authorizations or dry-run options.', { vm: 'solana' });
|
|
448
|
+
}
|
|
449
|
+
if (signedTransaction.originSignatures.length !== 1 ||
|
|
450
|
+
typeof signedTransaction.originSignatures[0] !== 'string' ||
|
|
451
|
+
signedTransaction.destinationSignature !== undefined ||
|
|
452
|
+
signedTransaction.targetExecutionSignature !== undefined) {
|
|
453
|
+
throw new InvalidSolanaTransactionArtifactError('submission requires exactly one raw origin signature and no destination or target signature', { intentId: signedTransaction.quote.intentId });
|
|
454
|
+
}
|
|
455
|
+
const prepared = resolveSolanaPrepared(ctx, signedTransaction, signedTransaction.quote.intentId, signedTransaction.quote);
|
|
456
|
+
const submitted = await workflows.submitSolanaIntent({
|
|
457
|
+
prepared,
|
|
458
|
+
signature: signedTransaction.originSignatures[0],
|
|
459
|
+
});
|
|
460
|
+
return {
|
|
461
|
+
type: 'intent',
|
|
462
|
+
id: submitted.intentId,
|
|
463
|
+
traceId: submitted.traceId,
|
|
464
|
+
...(submitted.sourceChains
|
|
465
|
+
? { sourceChains: [...submitted.sourceChains] }
|
|
466
|
+
: {}),
|
|
467
|
+
targetChain: submitted.targetChain,
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
assertSupportedSignData(signedTransaction.quote.signData);
|
|
263
471
|
// Fast path for the same-instance signed object; otherwise (cross-instance
|
|
264
472
|
// replay or caller-tampered signatures) rebuild from the public shape.
|
|
265
473
|
const cached = signedIntents.get(signedTransaction);
|
|
@@ -388,6 +596,10 @@ export function createAccountFacade(compatibilityConfig, publicConfig, compositi
|
|
|
388
596
|
publicConfig.solana.address) {
|
|
389
597
|
return publicConfig.solana.address;
|
|
390
598
|
}
|
|
599
|
+
if (capturedSolanaIdentity) {
|
|
600
|
+
return locateSwig(asSwigNamespace('dev-v1'), capturedSolanaIdentity)
|
|
601
|
+
.wallet;
|
|
602
|
+
}
|
|
391
603
|
throw new AccountVmNotConfiguredError('solana');
|
|
392
604
|
}
|
|
393
605
|
if (vm !== 'evm' || !publicConfig.evm) {
|
|
@@ -573,6 +785,8 @@ function assertSupportedSignData(signData) {
|
|
|
573
785
|
for (const payload of payloads) {
|
|
574
786
|
if (!payload ||
|
|
575
787
|
typeof payload !== 'object' ||
|
|
788
|
+
(payload.kind !== undefined &&
|
|
789
|
+
payload.kind !== 'eip712') ||
|
|
576
790
|
typeof payload.primaryType !== 'string' ||
|
|
577
791
|
!payload.domain ||
|
|
578
792
|
typeof payload.types !== 'object' ||
|
|
@@ -581,6 +795,76 @@ function assertSupportedSignData(signData) {
|
|
|
581
795
|
}
|
|
582
796
|
}
|
|
583
797
|
}
|
|
798
|
+
function isSolanaOrigin(transaction) {
|
|
799
|
+
return ('chain' in transaction &&
|
|
800
|
+
typeof transaction.chain === 'object' &&
|
|
801
|
+
transaction.chain !== null &&
|
|
802
|
+
'kind' in transaction.chain &&
|
|
803
|
+
transaction.chain.kind === 'svm');
|
|
804
|
+
}
|
|
805
|
+
function assertSolanaObjectKeys(value, allowed, label) {
|
|
806
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
807
|
+
throw new UnsupportedAccountCapabilityError(`Managed Solana ${label} must be an object.`, { vm: 'solana', field: label });
|
|
808
|
+
}
|
|
809
|
+
const unsupported = Object.keys(value).find((key) => !allowed.includes(key));
|
|
810
|
+
if (unsupported) {
|
|
811
|
+
throw new UnsupportedAccountCapabilityError(`Solana-origin transfers do not support \`${label}.${unsupported}\`.`, { vm: 'solana', field: `${label}.${unsupported}` });
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
function assertSupportedSolanaTransaction(input, config) {
|
|
815
|
+
const allowed = new Set([
|
|
816
|
+
'chain',
|
|
817
|
+
'tokenRequests',
|
|
818
|
+
'recipient',
|
|
819
|
+
'sponsored',
|
|
820
|
+
'appFees',
|
|
821
|
+
'protocolFees',
|
|
822
|
+
]);
|
|
823
|
+
const unsupported = Object.keys(input).find((key) => !allowed.has(key));
|
|
824
|
+
if (unsupported) {
|
|
825
|
+
throw new UnsupportedAccountCapabilityError(`Solana-origin transfers do not support \`${unsupported}\`.`, { vm: 'solana', field: unsupported });
|
|
826
|
+
}
|
|
827
|
+
if (!config.solana || !('owner' in config.solana)) {
|
|
828
|
+
throw new UnsupportedAccountCapabilityError('A managed Solana source is required for Solana-origin transfers.', { vm: 'solana' });
|
|
829
|
+
}
|
|
830
|
+
solanaChainId(input.chain);
|
|
831
|
+
if (input.sponsored !== undefined && input.sponsored !== false) {
|
|
832
|
+
throw new UnsupportedAccountCapabilityError('Managed Solana transfers are not sponsorable; omit `sponsored` or set it to false.', { vm: 'solana' });
|
|
833
|
+
}
|
|
834
|
+
if (!Array.isArray(input.tokenRequests) || input.tokenRequests.length !== 1) {
|
|
835
|
+
throw new UnsupportedAccountCapabilityError('Managed Solana transfers require exactly one SPL token request.', { vm: 'solana' });
|
|
836
|
+
}
|
|
837
|
+
const request = input.tokenRequests[0];
|
|
838
|
+
assertSolanaObjectKeys(request, ['address', 'amount'], 'tokenRequests[0]');
|
|
839
|
+
if (typeof request.address !== 'string') {
|
|
840
|
+
throw new UnsupportedAccountCapabilityError('Managed Solana transfers require one valid SPL mint address.', { vm: 'solana' });
|
|
841
|
+
}
|
|
842
|
+
try {
|
|
843
|
+
solanaAddress(request.address);
|
|
844
|
+
}
|
|
845
|
+
catch {
|
|
846
|
+
throw new UnsupportedAccountCapabilityError('Managed Solana transfers require one valid SPL mint address.', { vm: 'solana' });
|
|
847
|
+
}
|
|
848
|
+
if (request.amount !== undefined &&
|
|
849
|
+
(typeof request.amount !== 'bigint' || request.amount <= 0n)) {
|
|
850
|
+
throw new UnsupportedAccountCapabilityError('A Solana token amount must be a positive bigint when provided.', { vm: 'solana' });
|
|
851
|
+
}
|
|
852
|
+
if (input.appFees !== undefined) {
|
|
853
|
+
assertSolanaObjectKeys(input.appFees, ['feeBps'], 'appFees');
|
|
854
|
+
}
|
|
855
|
+
if (input.protocolFees !== undefined) {
|
|
856
|
+
assertSolanaObjectKeys(input.protocolFees, ['feeBps'], 'protocolFees');
|
|
857
|
+
}
|
|
858
|
+
if (typeof input.recipient !== 'string') {
|
|
859
|
+
throw new UnsupportedAccountCapabilityError('Managed Solana transfers require an explicit recipient wallet.', { vm: 'solana' });
|
|
860
|
+
}
|
|
861
|
+
try {
|
|
862
|
+
solanaAddress(input.recipient);
|
|
863
|
+
}
|
|
864
|
+
catch {
|
|
865
|
+
throw new UnsupportedAccountCapabilityError('Managed Solana transfers require a valid recipient wallet.', { vm: 'solana' });
|
|
866
|
+
}
|
|
867
|
+
}
|
|
584
868
|
function assertSupportedTransaction(transaction, config) {
|
|
585
869
|
const input = transaction;
|
|
586
870
|
const hasChain = Object.hasOwn(input, 'chain') && input.chain !== undefined;
|
|
@@ -591,7 +875,8 @@ function assertSupportedTransaction(transaction, config) {
|
|
|
591
875
|
if (hasChain && typeof input.chain === 'object' && input.chain !== null) {
|
|
592
876
|
const chain = input.chain;
|
|
593
877
|
if (chain.kind === 'svm') {
|
|
594
|
-
|
|
878
|
+
assertSupportedSolanaTransaction(input, config);
|
|
879
|
+
return;
|
|
595
880
|
}
|
|
596
881
|
}
|
|
597
882
|
if (hasTarget && typeof input.targetChain === 'object' && input.targetChain) {
|
|
@@ -684,6 +969,20 @@ function assertSupportedTransaction(transaction, config) {
|
|
|
684
969
|
}
|
|
685
970
|
export function normalizeTransaction(transaction, config) {
|
|
686
971
|
assertSupportedTransaction(transaction, config);
|
|
972
|
+
if (isSolanaOrigin(transaction)) {
|
|
973
|
+
const request = transaction.tokenRequests[0];
|
|
974
|
+
return Object.freeze({
|
|
975
|
+
...transaction,
|
|
976
|
+
chain: Object.freeze({ ...transaction.chain }),
|
|
977
|
+
tokenRequests: [Object.freeze({ ...request })],
|
|
978
|
+
...(transaction.appFees
|
|
979
|
+
? { appFees: Object.freeze({ ...transaction.appFees }) }
|
|
980
|
+
: {}),
|
|
981
|
+
...(transaction.protocolFees
|
|
982
|
+
? { protocolFees: Object.freeze({ ...transaction.protocolFees }) }
|
|
983
|
+
: {}),
|
|
984
|
+
});
|
|
985
|
+
}
|
|
687
986
|
if ('targetChain' in transaction &&
|
|
688
987
|
transaction.targetChain !== undefined &&
|
|
689
988
|
'kind' in transaction.targetChain &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../../api/accounts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAEV,oBAAoB,EACrB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC7B,MAAM,kBAAkB,CAAA;AAWzB,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,WAAW,CAAA;AAElB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAA;IACnE,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAA;CACpD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,oBAAoB,GAAG,cAAc,CAOtE;
|
|
1
|
+
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../../api/accounts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,uBAAuB,EACxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAEV,oBAAoB,EACrB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC7B,MAAM,kBAAkB,CAAA;AAWzB,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,WAAW,CAAA;AAElB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAA;IACnE,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAC,OAAO,CAAC,CAAA;CACpD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,oBAAoB,GAAG,cAAc,CAOtE;AAiCD,wBAAgB,aAAa,CAAC,KAAK,CAAC,CAAC,SAAS,uBAAuB,EACnE,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,CAAC,GACR,iBAAiB,CAAC,CAAC,CAAC,CAgItB"}
|