Skip to content

Example: Creating an Order

Define your route parameters

In this simplified example, we send funds to a single recipient on Ethereum, who will receive 10 USDC.

client.ts
// configure output parameters (for this example, sends funds around and back to the user)
const recipientAddr = account.address;
const tokenAddr = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
const tokenDecimals = 6;
const tokenSymbol = 'USDC';
const tokenAmount = '10';

Derive the viewer account

Before requesting a quote, we need to derive the viewer account from the facilitator group and export its public key. The viewer is used to observe the order execution.

client.ts
import { FacilitatorKeyType } from '@silentswap/sdk';
 
// derive viewer account from the facilitator group
const viewer = await group.viewer();
 
// export its public key
const {
    publicKeyBytes: pk65_viewer,
} = viewer.exportPublicKey('*', FacilitatorKeyType.SECP256K1);

Request a Quote

At this stage, we must commit to the facilitator accounts we will use for the order. We do this by exporting the public keys of the facilitator group using a predetermined selection of coin types, and including the viewer public key in the quote request.

client.ts
import BigNumber from 'bignumber.js';
import { caip19FungibleEvmToken } from '@silentswap/sdk';
 
// export public keys for the facilitator group. this example is for only 1 output
const groupPublicKeys = (await group.exportPublicKeys(1, [
    ...PublicKeyArgGroups.GENERIC,
]));
 
// request a quote
const [quoteError, quoteResponse] = await silentswap.quote({
    signer: viemSigner.address,
    viewer: pk65_viewer,
    outputs: [
        {
            method: DeliveryMethod.SNIP,
            recipient: recipientAddr,
            asset: caip19FungibleEvmToken(1, tokenAddr),
            value: BigNumber(tokenAmount).shiftedBy(tokenDecimals).toFixed(0) as `${bigint}`,
            facilitatorPublicKeys: groupPublicKeys[0],
        },
    ],
});
 
if (quoteError || !quoteResponse) {
    throw new Error(`Failed to get quote: ${quoteError?.type}: ${quoteError?.error}`);
}

Review and sign authorizations

Assuming we are happy with the quote, we must sign the authorizations for the order (including meta txs, proxy authorizations, and the order intent itself). This is done using the EvmSigner abstraction and selecting the appropriate signer for each document.

client.ts
import { quoteResponseToEip712Document } from '@silentswap/sdk';
 
// sign authorizations
const signedAuths = await Promise.all(quoteResponse.authorizations.map(async g_auth => ({
    ...g_auth,
    signature: await (async () => {
        // EIP-3009 deposit
        if ('eip3009_deposit' === g_auth.type) {
            return await viemSigner.signEip712TypedData(g_auth.eip712);
        }
 
        throw Error(`Authorization instruction type not implemented: ${g_auth.type}`);
    })(),
})));
 
// sign the order's EIP-712
const orderDoc = quoteResponseToEip712Document(quoteResponse);
const signedQuote = await viemSigner.signEip712TypedData(orderDoc);
 
// approve proxy authorizations
const facilitatorReplies = await group.approveProxyAuthorizations(quoteResponse.facilitators, {
    proxyPublicKey: silentswap.proxyPublicKey,
});

Place the order

Placing the order is a simple matter of sending a request to the SilentSwap service, including the quote, signed authorizations, and facilitator replies.

client.ts
// place the order
const [orderError, orderResponse] = await silentswap.order({
    quote: quoteResponse.quote,
    quoteId: quoteResponse.quoteId,
    authorizations: signedAuths,
    eip712Domain: orderDoc.domain,
    signature: signedQuote,
    facilitators: facilitatorReplies,
});
 
if (orderError || !orderResponse) {
    throw new Error(`Failed to place order: ${orderError?.type}: ${orderError?.error}`);
}
 
console.log(`Placed order ${orderResponse.response.orderId}`);