resolver picker
This commit is contained in:
@@ -6,6 +6,7 @@ import { useWallet, useKitTransactionSigner } from '@solana/connector/react'
|
|||||||
import { ListingDetail } from '@/components/ListingDetail'
|
import { ListingDetail } from '@/components/ListingDetail'
|
||||||
import { useTx } from '@/hooks/useTx'
|
import { useTx } from '@/hooks/useTx'
|
||||||
import { useListing } from '@/hooks/useListing'
|
import { useListing } from '@/hooks/useListing'
|
||||||
|
import { useResolvers } from '@/hooks/useResolvers'
|
||||||
import {
|
import {
|
||||||
getCloseListingInstruction,
|
getCloseListingInstruction,
|
||||||
getCreateOrderInstructionAsync,
|
getCreateOrderInstructionAsync,
|
||||||
@@ -13,6 +14,8 @@ import {
|
|||||||
deriveEscrowId,
|
deriveEscrowId,
|
||||||
} from '@solisting/sdk'
|
} from '@solisting/sdk'
|
||||||
import { DESCRO_PROGRAM_ADDRESS } from '@descro/sdk'
|
import { DESCRO_PROGRAM_ADDRESS } from '@descro/sdk'
|
||||||
|
import { ResolverType } from '@descro/sdk'
|
||||||
|
import { Button } from '@/components/ui/Button'
|
||||||
import type { Address } from '@solisting/sdk'
|
import type { Address } from '@solisting/sdk'
|
||||||
|
|
||||||
const SYSTEM_PROGRAM = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>
|
const SYSTEM_PROGRAM = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>
|
||||||
@@ -24,7 +27,10 @@ export default function ListingPage({ params }: { params: Promise<{ pk: string }
|
|||||||
const { signer } = useKitTransactionSigner()
|
const { signer } = useKitTransactionSigner()
|
||||||
const sendTx = useTx()
|
const sendTx = useTx()
|
||||||
const { data: listing } = useListing(pk as Address)
|
const { data: listing } = useListing(pk as Address)
|
||||||
|
const { data: resolvers = [] } = useResolvers()
|
||||||
const [orderLoading, setOrderLoading] = useState(false)
|
const [orderLoading, setOrderLoading] = useState(false)
|
||||||
|
const [showResolverPicker, setShowResolverPicker] = useState(false)
|
||||||
|
const [selectedResolver, setSelectedResolver] = useState<Address | null>(null)
|
||||||
|
|
||||||
async function handleClose() {
|
async function handleClose() {
|
||||||
if (!signer) return
|
if (!signer) return
|
||||||
@@ -33,8 +39,14 @@ export default function ListingPage({ params }: { params: Promise<{ pk: string }
|
|||||||
router.push('/listings')
|
router.push('/listings')
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handlePlaceOrder() {
|
function openPlaceOrder() {
|
||||||
|
setSelectedResolver(null)
|
||||||
|
setShowResolverPicker(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleConfirmOrder() {
|
||||||
if (!signer || !account || !listing) return
|
if (!signer || !account || !listing) return
|
||||||
|
setShowResolverPicker(false)
|
||||||
setOrderLoading(true)
|
setOrderLoading(true)
|
||||||
try {
|
try {
|
||||||
const orderId = BigInt(Date.now())
|
const orderId = BigInt(Date.now())
|
||||||
@@ -50,7 +62,7 @@ export default function ListingPage({ params }: { params: Promise<{ pk: string }
|
|||||||
descroProgram: DESCRO_PROGRAM_ADDRESS,
|
descroProgram: DESCRO_PROGRAM_ADDRESS,
|
||||||
orderId,
|
orderId,
|
||||||
escrowId,
|
escrowId,
|
||||||
resolver: account as Address,
|
resolver: selectedResolver,
|
||||||
paymentCurrency: { __kind: 'Sol' },
|
paymentCurrency: { __kind: 'Sol' },
|
||||||
expectedAmount: listing.data.price,
|
expectedAmount: listing.data.price,
|
||||||
maxSlippageBps: 0,
|
maxSlippageBps: 0,
|
||||||
@@ -67,13 +79,101 @@ export default function ListingPage({ params }: { params: Promise<{ pk: string }
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const acceptedResolvers = listing?.data.acceptedResolvers ?? []
|
||||||
|
const visibleResolvers = acceptedResolvers.length > 0
|
||||||
|
? resolvers.filter((r) => acceptedResolvers.includes(r.pda as Address))
|
||||||
|
: resolvers
|
||||||
|
const mustSelectResolver = acceptedResolvers.length > 0
|
||||||
|
const confirmDisabled = mustSelectResolver && !selectedResolver
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListingDetail
|
<>
|
||||||
pk={pk as Address}
|
<ListingDetail
|
||||||
walletAddress={account ?? null}
|
pk={pk as Address}
|
||||||
onUpdate={() => router.push(`/listing/create?edit=${pk}`)}
|
walletAddress={account ?? null}
|
||||||
onClose={handleClose}
|
onUpdate={() => router.push(`/listing/create?edit=${pk}`)}
|
||||||
onPlaceOrder={orderLoading ? undefined : handlePlaceOrder}
|
onClose={handleClose}
|
||||||
/>
|
onPlaceOrder={orderLoading ? undefined : openPlaceOrder}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{showResolverPicker && (
|
||||||
|
<div
|
||||||
|
style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.55)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 100 }}
|
||||||
|
onClick={(e) => { if (e.target === e.currentTarget) setShowResolverPicker(false) }}
|
||||||
|
>
|
||||||
|
<div style={{ background: 'var(--bg)', border: '1px solid var(--bd)', borderRadius: 'var(--radius)', padding: '28px 28px 24px', width: 440, maxWidth: '90vw', maxHeight: '80vh', overflow: 'auto' }}>
|
||||||
|
<div style={{ fontSize: 11, fontWeight: 600, letterSpacing: '.14em', color: 'var(--mut)', marginBottom: 12 }}>PLACE ORDER</div>
|
||||||
|
<h2 style={{ margin: '0 0 8px', fontSize: 19, fontWeight: 700 }}>Select Resolver</h2>
|
||||||
|
<p style={{ margin: '0 0 20px', fontSize: 13, color: 'var(--mut)', lineHeight: 1.55 }}>
|
||||||
|
{mustSelectResolver
|
||||||
|
? 'This listing requires one of the following resolvers for dispute resolution.'
|
||||||
|
: 'Choose a resolver for dispute resolution, or proceed without one.'}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 22 }}>
|
||||||
|
{!mustSelectResolver && (
|
||||||
|
<ResolverOption
|
||||||
|
selected={selectedResolver === null}
|
||||||
|
onClick={() => setSelectedResolver(null)}
|
||||||
|
label="No resolver"
|
||||||
|
sublabel="Disputes cannot be resolved on-chain"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{visibleResolvers.map((r) => (
|
||||||
|
<ResolverOption
|
||||||
|
key={r.pda}
|
||||||
|
selected={selectedResolver === r.pda}
|
||||||
|
onClick={() => setSelectedResolver(r.pda as Address)}
|
||||||
|
label={`${r.pda.slice(0, 8)}…${r.pda.slice(-6)}`}
|
||||||
|
sublabel={ResolverType[r.data.resolverType as number] as string}
|
||||||
|
mono
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{visibleResolvers.length === 0 && mustSelectResolver && (
|
||||||
|
<div style={{ fontSize: 13, color: 'var(--mut)', padding: '12px 0' }}>
|
||||||
|
No registered resolvers found for this listing.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
|
||||||
|
<Button variant="ghost" onClick={() => setShowResolverPicker(false)}>Cancel</Button>
|
||||||
|
<Button onClick={handleConfirmOrder} disabled={confirmDisabled}>Place Order</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ResolverOption({ selected, onClick, label, sublabel, mono }: {
|
||||||
|
selected: boolean
|
||||||
|
onClick: () => void
|
||||||
|
label: string
|
||||||
|
sublabel?: string
|
||||||
|
mono?: boolean
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={onClick}
|
||||||
|
style={{
|
||||||
|
display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
|
||||||
|
padding: '11px 14px', borderRadius: 9, cursor: 'pointer', textAlign: 'left',
|
||||||
|
background: selected ? 'var(--accSoft)' : 'var(--bg3)',
|
||||||
|
border: `1px solid ${selected ? 'var(--accBd)' : 'var(--bd)'}`,
|
||||||
|
color: 'var(--tx)',
|
||||||
|
transition: 'background .12s, border-color .12s',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span style={{ fontFamily: mono ? 'var(--font-mono)' : undefined, fontSize: mono ? 12.5 : 13, fontWeight: selected ? 600 : mono ? 400 : 600 }}>
|
||||||
|
{label}
|
||||||
|
</span>
|
||||||
|
{sublabel && (
|
||||||
|
<span style={{ fontSize: 11.5, color: 'var(--mut)', flexShrink: 0 }}>
|
||||||
|
{sublabel}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use crate::state::{Currency, ListingAccount, OrderAccount};
|
|||||||
use anchor_lang::prelude::*;
|
use anchor_lang::prelude::*;
|
||||||
|
|
||||||
#[derive(Accounts)]
|
#[derive(Accounts)]
|
||||||
#[instruction(order_id: u64, escrow_id: u64, resolver: Pubkey, payment_currency: Currency)]
|
#[instruction(order_id: u64, escrow_id: u64, resolver: Option<Pubkey>, payment_currency: Currency)]
|
||||||
pub struct CreateOrder<'info> {
|
pub struct CreateOrder<'info> {
|
||||||
#[account(mut)]
|
#[account(mut)]
|
||||||
pub buyer: Signer<'info>,
|
pub buyer: Signer<'info>,
|
||||||
@@ -67,7 +67,7 @@ pub fn handler(
|
|||||||
ctx: Context<CreateOrder>,
|
ctx: Context<CreateOrder>,
|
||||||
order_id: u64,
|
order_id: u64,
|
||||||
escrow_id: u64,
|
escrow_id: u64,
|
||||||
resolver: Pubkey,
|
resolver: Option<Pubkey>,
|
||||||
payment_currency: Currency,
|
payment_currency: Currency,
|
||||||
expected_amount: u64,
|
expected_amount: u64,
|
||||||
max_slippage_bps: u16,
|
max_slippage_bps: u16,
|
||||||
@@ -80,10 +80,13 @@ pub fn handler(
|
|||||||
let listing = &ctx.accounts.listing_account;
|
let listing = &ctx.accounts.listing_account;
|
||||||
|
|
||||||
if !listing.accepted_resolvers.is_empty() {
|
if !listing.accepted_resolvers.is_empty() {
|
||||||
require!(
|
match resolver {
|
||||||
listing.accepted_resolvers.contains(&resolver),
|
Some(r) => require!(
|
||||||
SolistingError::ResolverNotAccepted
|
listing.accepted_resolvers.contains(&r),
|
||||||
);
|
SolistingError::ResolverNotAccepted
|
||||||
|
),
|
||||||
|
None => return err!(SolistingError::ResolverNotAccepted),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let amount = if payment_currency == listing.canonical_currency {
|
let amount = if payment_currency == listing.canonical_currency {
|
||||||
@@ -143,7 +146,7 @@ pub fn handler(
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
amount,
|
amount,
|
||||||
Some(resolver),
|
resolver,
|
||||||
escrow_id,
|
escrow_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ pub mod solisting {
|
|||||||
ctx: Context<CreateOrder>,
|
ctx: Context<CreateOrder>,
|
||||||
order_id: u64,
|
order_id: u64,
|
||||||
escrow_id: u64,
|
escrow_id: u64,
|
||||||
resolver: Pubkey,
|
resolver: Option<Pubkey>,
|
||||||
payment_currency: state::Currency,
|
payment_currency: state::Currency,
|
||||||
expected_amount: u64,
|
expected_amount: u64,
|
||||||
max_slippage_bps: u16,
|
max_slippage_bps: u16,
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ pub struct OrderAccount {
|
|||||||
pub listing: Pubkey,
|
pub listing: Pubkey,
|
||||||
pub buyer: Pubkey,
|
pub buyer: Pubkey,
|
||||||
pub seller: Pubkey,
|
pub seller: Pubkey,
|
||||||
pub resolver: Pubkey,
|
pub resolver: Option<Pubkey>,
|
||||||
/// The currency the buyer chose to pay in.
|
/// The currency the buyer chose to pay in.
|
||||||
pub payment_currency: Currency,
|
pub payment_currency: Currency,
|
||||||
/// Actual amount paid (may differ from price when oracle-converted).
|
/// Actual amount paid (may differ from price when oracle-converted).
|
||||||
|
|||||||
@@ -195,7 +195,6 @@ pub fn ix_create_order(
|
|||||||
canonical_oracle: Option<Pubkey>,
|
canonical_oracle: Option<Pubkey>,
|
||||||
target_oracle: Option<Pubkey>,
|
target_oracle: Option<Pubkey>,
|
||||||
) -> Instruction {
|
) -> Instruction {
|
||||||
let resolver = Pubkey::new_unique();
|
|
||||||
ix_create_order_with_resolver(
|
ix_create_order_with_resolver(
|
||||||
buyer,
|
buyer,
|
||||||
seller,
|
seller,
|
||||||
@@ -205,7 +204,7 @@ pub fn ix_create_order(
|
|||||||
max_slippage_bps,
|
max_slippage_bps,
|
||||||
canonical_oracle,
|
canonical_oracle,
|
||||||
target_oracle,
|
target_oracle,
|
||||||
resolver,
|
Some(Pubkey::new_unique()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +218,7 @@ pub fn ix_create_order_with_resolver(
|
|||||||
max_slippage_bps: u16,
|
max_slippage_bps: u16,
|
||||||
canonical_oracle: Option<Pubkey>,
|
canonical_oracle: Option<Pubkey>,
|
||||||
target_oracle: Option<Pubkey>,
|
target_oracle: Option<Pubkey>,
|
||||||
resolver: Pubkey,
|
resolver: Option<Pubkey>,
|
||||||
) -> Instruction {
|
) -> Instruction {
|
||||||
let listing = listing_pda(seller, listing_id);
|
let listing = listing_pda(seller, listing_id);
|
||||||
let order = order_pda(listing, *buyer, order_id);
|
let order = order_pda(listing, *buyer, order_id);
|
||||||
@@ -264,7 +263,7 @@ pub fn ix_accept_order(
|
|||||||
buyer: &Pubkey,
|
buyer: &Pubkey,
|
||||||
order_id: u64,
|
order_id: u64,
|
||||||
escrow_id: u64,
|
escrow_id: u64,
|
||||||
resolver: Pubkey,
|
resolver: Option<Pubkey>,
|
||||||
) -> Instruction {
|
) -> Instruction {
|
||||||
let listing_account = listing_pda(seller, listing_id);
|
let listing_account = listing_pda(seller, listing_id);
|
||||||
let order_account = order_pda(listing_account, *buyer, order_id);
|
let order_account = order_pda(listing_account, *buyer, order_id);
|
||||||
@@ -276,7 +275,7 @@ pub fn ix_accept_order(
|
|||||||
&solisting::instruction::AcceptOrder {}.data(),
|
&solisting::instruction::AcceptOrder {}.data(),
|
||||||
solisting::accounts::AcceptOrder {
|
solisting::accounts::AcceptOrder {
|
||||||
seller: *seller,
|
seller: *seller,
|
||||||
resolver,
|
resolver: resolver.unwrap_or(system_program::ID),
|
||||||
listing_account,
|
listing_account,
|
||||||
order_account,
|
order_account,
|
||||||
escrow_account,
|
escrow_account,
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ fn create_order_fails_if_resolver_not_accepted() {
|
|||||||
&mut svm,
|
&mut svm,
|
||||||
&[ix_create_order_with_resolver(
|
&[ix_create_order_with_resolver(
|
||||||
&buyer.pubkey(), &seller.pubkey(), listing_id, 1,
|
&buyer.pubkey(), &seller.pubkey(), listing_id, 1,
|
||||||
Currency::Sol, 0, None, None, Pubkey::new_unique(),
|
Currency::Sol, 0, None, None, Some(Pubkey::new_unique()),
|
||||||
)],
|
)],
|
||||||
&[&buyer],
|
&[&buyer],
|
||||||
);
|
);
|
||||||
@@ -152,7 +152,7 @@ fn seller_accept_creates_active_descro_escrow() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let order_key = order_pda(listing_key, buyer.pubkey(), order_id);
|
let order_key = order_pda(listing_key, buyer.pubkey(), order_id);
|
||||||
assert!(svm.get_account(&order_key).is_none());
|
assert!(svm.get_account(&order_key).is_some());
|
||||||
|
|
||||||
let listing = read_listing(&svm, &seller.pubkey(), listing_id);
|
let listing = read_listing(&svm, &seller.pubkey(), listing_id);
|
||||||
assert_eq!(listing.quantity_reserved, 0);
|
assert_eq!(listing.quantity_reserved, 0);
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import {
|
|||||||
getBytesEncoder,
|
getBytesEncoder,
|
||||||
getI64Decoder,
|
getI64Decoder,
|
||||||
getI64Encoder,
|
getI64Encoder,
|
||||||
|
getOptionDecoder,
|
||||||
|
getOptionEncoder,
|
||||||
getStructDecoder,
|
getStructDecoder,
|
||||||
getStructEncoder,
|
getStructEncoder,
|
||||||
getU64Decoder,
|
getU64Decoder,
|
||||||
@@ -38,6 +40,8 @@ import {
|
|||||||
type FetchAccountsConfig,
|
type FetchAccountsConfig,
|
||||||
type MaybeAccount,
|
type MaybeAccount,
|
||||||
type MaybeEncodedAccount,
|
type MaybeEncodedAccount,
|
||||||
|
type Option,
|
||||||
|
type OptionOrNullable,
|
||||||
type ReadonlyUint8Array,
|
type ReadonlyUint8Array,
|
||||||
} from "@solana/kit";
|
} from "@solana/kit";
|
||||||
import {
|
import {
|
||||||
@@ -61,7 +65,7 @@ export type SolistingStateOrderAccount = {
|
|||||||
listing: Address;
|
listing: Address;
|
||||||
buyer: Address;
|
buyer: Address;
|
||||||
seller: Address;
|
seller: Address;
|
||||||
resolver: Address;
|
resolver: Option<Address>;
|
||||||
/** The currency the buyer chose to pay in. */
|
/** The currency the buyer chose to pay in. */
|
||||||
paymentCurrency: SolistingStateCurrency;
|
paymentCurrency: SolistingStateCurrency;
|
||||||
/** Actual amount paid (may differ from price when oracle-converted). */
|
/** Actual amount paid (may differ from price when oracle-converted). */
|
||||||
@@ -79,7 +83,7 @@ export type SolistingStateOrderAccountArgs = {
|
|||||||
listing: Address;
|
listing: Address;
|
||||||
buyer: Address;
|
buyer: Address;
|
||||||
seller: Address;
|
seller: Address;
|
||||||
resolver: Address;
|
resolver: OptionOrNullable<Address>;
|
||||||
/** The currency the buyer chose to pay in. */
|
/** The currency the buyer chose to pay in. */
|
||||||
paymentCurrency: SolistingStateCurrencyArgs;
|
paymentCurrency: SolistingStateCurrencyArgs;
|
||||||
/** Actual amount paid (may differ from price when oracle-converted). */
|
/** Actual amount paid (may differ from price when oracle-converted). */
|
||||||
@@ -101,7 +105,7 @@ export function getSolistingStateOrderAccountEncoder(): Encoder<SolistingStateOr
|
|||||||
["listing", getAddressEncoder()],
|
["listing", getAddressEncoder()],
|
||||||
["buyer", getAddressEncoder()],
|
["buyer", getAddressEncoder()],
|
||||||
["seller", getAddressEncoder()],
|
["seller", getAddressEncoder()],
|
||||||
["resolver", getAddressEncoder()],
|
["resolver", getOptionEncoder(getAddressEncoder())],
|
||||||
["paymentCurrency", getSolistingStateCurrencyEncoder()],
|
["paymentCurrency", getSolistingStateCurrencyEncoder()],
|
||||||
["amount", getU64Encoder()],
|
["amount", getU64Encoder()],
|
||||||
["escrowAccount", getAddressEncoder()],
|
["escrowAccount", getAddressEncoder()],
|
||||||
@@ -124,7 +128,7 @@ export function getSolistingStateOrderAccountDecoder(): Decoder<SolistingStateOr
|
|||||||
["listing", getAddressDecoder()],
|
["listing", getAddressDecoder()],
|
||||||
["buyer", getAddressDecoder()],
|
["buyer", getAddressDecoder()],
|
||||||
["seller", getAddressDecoder()],
|
["seller", getAddressDecoder()],
|
||||||
["resolver", getAddressDecoder()],
|
["resolver", getOptionDecoder(getAddressDecoder())],
|
||||||
["paymentCurrency", getSolistingStateCurrencyDecoder()],
|
["paymentCurrency", getSolistingStateCurrencyDecoder()],
|
||||||
["amount", getU64Decoder()],
|
["amount", getU64Decoder()],
|
||||||
["escrowAccount", getAddressDecoder()],
|
["escrowAccount", getAddressDecoder()],
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import {
|
|||||||
getAddressEncoder,
|
getAddressEncoder,
|
||||||
getBytesDecoder,
|
getBytesDecoder,
|
||||||
getBytesEncoder,
|
getBytesEncoder,
|
||||||
|
getOptionDecoder,
|
||||||
|
getOptionEncoder,
|
||||||
getProgramDerivedAddress,
|
getProgramDerivedAddress,
|
||||||
getStructDecoder,
|
getStructDecoder,
|
||||||
getStructEncoder,
|
getStructEncoder,
|
||||||
@@ -33,6 +35,8 @@ import {
|
|||||||
type Instruction,
|
type Instruction,
|
||||||
type InstructionWithAccounts,
|
type InstructionWithAccounts,
|
||||||
type InstructionWithData,
|
type InstructionWithData,
|
||||||
|
type Option,
|
||||||
|
type OptionOrNullable,
|
||||||
type ReadonlyAccount,
|
type ReadonlyAccount,
|
||||||
type ReadonlyUint8Array,
|
type ReadonlyUint8Array,
|
||||||
type TransactionSigner,
|
type TransactionSigner,
|
||||||
@@ -121,7 +125,7 @@ export type CreateOrderInstructionData = {
|
|||||||
discriminator: ReadonlyUint8Array;
|
discriminator: ReadonlyUint8Array;
|
||||||
orderId: bigint;
|
orderId: bigint;
|
||||||
escrowId: bigint;
|
escrowId: bigint;
|
||||||
resolver: Address;
|
resolver: Option<Address>;
|
||||||
paymentCurrency: SolistingStateCurrency;
|
paymentCurrency: SolistingStateCurrency;
|
||||||
expectedAmount: bigint;
|
expectedAmount: bigint;
|
||||||
maxSlippageBps: number;
|
maxSlippageBps: number;
|
||||||
@@ -130,7 +134,7 @@ export type CreateOrderInstructionData = {
|
|||||||
export type CreateOrderInstructionDataArgs = {
|
export type CreateOrderInstructionDataArgs = {
|
||||||
orderId: number | bigint;
|
orderId: number | bigint;
|
||||||
escrowId: number | bigint;
|
escrowId: number | bigint;
|
||||||
resolver: Address;
|
resolver: OptionOrNullable<Address>;
|
||||||
paymentCurrency: SolistingStateCurrencyArgs;
|
paymentCurrency: SolistingStateCurrencyArgs;
|
||||||
expectedAmount: number | bigint;
|
expectedAmount: number | bigint;
|
||||||
maxSlippageBps: number;
|
maxSlippageBps: number;
|
||||||
@@ -142,7 +146,7 @@ export function getCreateOrderInstructionDataEncoder(): Encoder<CreateOrderInstr
|
|||||||
["discriminator", fixEncoderSize(getBytesEncoder(), 8)],
|
["discriminator", fixEncoderSize(getBytesEncoder(), 8)],
|
||||||
["orderId", getU64Encoder()],
|
["orderId", getU64Encoder()],
|
||||||
["escrowId", getU64Encoder()],
|
["escrowId", getU64Encoder()],
|
||||||
["resolver", getAddressEncoder()],
|
["resolver", getOptionEncoder(getAddressEncoder())],
|
||||||
["paymentCurrency", getSolistingStateCurrencyEncoder()],
|
["paymentCurrency", getSolistingStateCurrencyEncoder()],
|
||||||
["expectedAmount", getU64Encoder()],
|
["expectedAmount", getU64Encoder()],
|
||||||
["maxSlippageBps", getU16Encoder()],
|
["maxSlippageBps", getU16Encoder()],
|
||||||
@@ -156,7 +160,7 @@ export function getCreateOrderInstructionDataDecoder(): Decoder<CreateOrderInstr
|
|||||||
["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
|
["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
|
||||||
["orderId", getU64Decoder()],
|
["orderId", getU64Decoder()],
|
||||||
["escrowId", getU64Decoder()],
|
["escrowId", getU64Decoder()],
|
||||||
["resolver", getAddressDecoder()],
|
["resolver", getOptionDecoder(getAddressDecoder())],
|
||||||
["paymentCurrency", getSolistingStateCurrencyDecoder()],
|
["paymentCurrency", getSolistingStateCurrencyDecoder()],
|
||||||
["expectedAmount", getU64Decoder()],
|
["expectedAmount", getU64Decoder()],
|
||||||
["maxSlippageBps", getU16Decoder()],
|
["maxSlippageBps", getU16Decoder()],
|
||||||
|
|||||||
@@ -21,15 +21,15 @@ type GetRpc = Rpc<GetAccountInfoApi>
|
|||||||
// 8: listing (32)
|
// 8: listing (32)
|
||||||
// 40: buyer (32)
|
// 40: buyer (32)
|
||||||
// 72: seller (32)
|
// 72: seller (32)
|
||||||
// 104: resolver (32)
|
// 104: resolver Option<Pubkey> = 1 byte tag + 32 bytes = 33 bytes
|
||||||
// 136: paymentCurrency — Sol variant = 1 byte tag + 0 data = 1 byte total
|
// 137: paymentCurrency — Sol variant = 1 byte tag + 0 data = 1 byte total
|
||||||
// 137: amount (8)
|
// 138: amount (8)
|
||||||
// 145: escrowAccount (32)
|
// 146: escrowAccount (32)
|
||||||
const LISTING_OFFSET = 8n
|
const LISTING_OFFSET = 8n
|
||||||
const BUYER_OFFSET = 40n
|
const BUYER_OFFSET = 40n
|
||||||
// escrowAccount offset is only valid for Sol-currency orders.
|
// escrowAccount offset is only valid for Sol-currency orders.
|
||||||
// SPL orders (currently rejected by the program with SplNotImplemented) would sit at offset 178.
|
// SPL orders (currently rejected by the program with SplNotImplemented) would sit at offset 179.
|
||||||
const ESCROW_ACCOUNT_OFFSET = 145n
|
const ESCROW_ACCOUNT_OFFSET = 146n
|
||||||
|
|
||||||
type RawGpaResult = Array<{
|
type RawGpaResult = Array<{
|
||||||
pubkey: Address
|
pubkey: Address
|
||||||
|
|||||||
@@ -835,7 +835,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "resolver",
|
"name": "resolver",
|
||||||
"type": "pubkey"
|
"type": {
|
||||||
|
"option": "pubkey"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "payment_currency",
|
"name": "payment_currency",
|
||||||
@@ -1461,7 +1463,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "resolver",
|
"name": "resolver",
|
||||||
"type": "pubkey"
|
"type": {
|
||||||
|
"option": "pubkey"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "payment_currency",
|
"name": "payment_currency",
|
||||||
|
|||||||
Reference in New Issue
Block a user