-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: jupiter swap and tx frame DCP-1806 (#3)
* fix: remove GITHUB_TOKEN Signed-off-by: Jimmy Madrigal <[email protected]> * feat: transaction example Signed-off-by: Jimmy Madrigal <[email protected]> * fix: remove receive from frame transactions Signed-off-by: Jimmy Madrigal <[email protected]> * fix: remove legacy button Signed-off-by: Jimmy Madrigal <[email protected]> * feat: jupiter swap example Signed-off-by: Jimmy Madrigal <[email protected]> * fix: pr feedback Signed-off-by: Jimmy Madrigal <[email protected]> --------- Signed-off-by: Jimmy Madrigal <[email protected]>
- Loading branch information
1 parent
6acd3f9
commit e423d2f
Showing
68 changed files
with
15,574 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
registry=https://registry.npmjs.org | ||
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
registry=https://registry.npmjs.org | ||
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
registry=https://registry.npmjs.org | ||
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
.yarn/install-state.gz | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
registry=https://registry.npmjs.org |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"typescript.tsdk": "node_modules/typescript/lib", | ||
"typescript.enablePromptUseWorkspaceTsdk": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Jupiter Swap | ||
|
||
This frame example allow the usage of jupiter swap api. | ||
|
||
This is a [Next.js](https://nextjs.org/) project that uses frames.js, [DSCVR frames adapter](https://docs.dscvr.one/build/frames/frame-concepts.html#frames-adapter) and [DSCVR API](https://docs.dscvr.one/build/dscvr-api/). | ||
|
||
## Getting Started | ||
|
||
First, install the package | ||
|
||
```bash | ||
pnpm install | ||
``` | ||
|
||
Then, run the development server: | ||
|
||
```bash | ||
pnpm dev | ||
``` | ||
|
||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result, a blank screen will be shown, but the html headers will show the frames information. | ||
|
||
## Debug your changes | ||
|
||
Since all of the action happens in the headers, go ahead an try our [DSCVR frame validator](https://dscvr.one/dev/frames): | ||
|
||
1. Once the project is running on port 3000, run `npx localtunnel --port 3000` | ||
2. Copy the provided url | ||
3. Go to [DSCVR frame validator](https://dscvr.one/dev/frames) | ||
4. Play with your frame! | ||
|
||
## Learn More | ||
|
||
In this example a frame message is validated by the [DSCVR frame adapter](https://docs.dscvr.one/build/frames/frame-concepts.html#frames-adapter) to make sure is a DSCVR message, then the information for the current user and content is gathered using the [DSCVR API](https://docs.dscvr.one/build/dscvr-api/) and shown as a response. | ||
|
||
To learn more about Frames visit our [documentation](https://docs.dscvr.one/). | ||
|
||
## Deploy on Vercel | ||
|
||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. | ||
|
||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = { | ||
async headers() { | ||
return [ | ||
{ | ||
// matching all API routes | ||
source: '/:path*', | ||
headers: [ | ||
{ key: 'Access-Control-Allow-Credentials', value: 'true' }, | ||
{ key: 'Access-Control-Allow-Origin', value: '*' }, | ||
{ key: 'Access-Control-Allow-Methods', value: 'GET,POST' }, | ||
{ | ||
key: 'Access-Control-Allow-Headers', | ||
value: | ||
'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version', | ||
}, | ||
], | ||
}, | ||
]; | ||
}, | ||
}; | ||
|
||
export default nextConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "jupiter-swap", | ||
"version": "0.1.0", | ||
"scripts": { | ||
"dev": "next dev", | ||
"build": "next build", | ||
"start": "next start", | ||
"lint": "next lint" | ||
}, | ||
"dependencies": { | ||
"@dscvr-one/frames-adapter": "^2.0.3", | ||
"@solana/web3.js": "^1.91.4", | ||
"@urql/core": "^4.3.0", | ||
"bs58": "^5.0.0", | ||
"frames.js": "^0.8.5", | ||
"gql.tada": "^1.3.0", | ||
"next": "14.1.2", | ||
"react": "^18", | ||
"react-dom": "^18" | ||
}, | ||
"devDependencies": { | ||
"@0no-co/graphqlsp": "^1.4.2", | ||
"@types/node": "^20", | ||
"@types/react": "^18", | ||
"@types/react-dom": "^18", | ||
"autoprefixer": "^10.0.1", | ||
"eslint": "^8", | ||
"eslint-config-next": "14.1.2", | ||
"postcss": "^8", | ||
"tailwindcss": "^3.3.0", | ||
"typescript": "^5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Client, cacheExchange, fetchExchange } from '@urql/core'; | ||
import { initGraphQLTada } from 'gql.tada'; | ||
import { introspection } from '../graphql-env'; | ||
|
||
export const graphql = initGraphQLTada<{ | ||
introspection: introspection; | ||
scalars: { | ||
DscvrId: string; | ||
ContentId: string; | ||
}; | ||
}>(); | ||
|
||
const getDataQuery = graphql(` | ||
query getData($id: DscvrId!, $contentId: ContentId!, $hasContent: Boolean!) { | ||
user(id: $id) { | ||
id | ||
username | ||
} | ||
content(id: $contentId) @include(if: $hasContent) { | ||
id | ||
creator { | ||
username | ||
} | ||
contentType | ||
portal { | ||
name | ||
iconUrl | ||
} | ||
} | ||
} | ||
`); | ||
|
||
export const dscvrApiUrl = 'https://api.dscvr.one/graphql'; | ||
|
||
export const getData = async (id: string, contentId?: string) => { | ||
const client = new Client({ | ||
url: dscvrApiUrl, | ||
exchanges: [cacheExchange, fetchExchange], | ||
}); | ||
|
||
const result = await client | ||
.query(getDataQuery, { | ||
id, | ||
contentId: contentId || '', | ||
hasContent: !!contentId, | ||
}) | ||
.toPromise(); | ||
if (result.error) { | ||
let message = result.error.message; | ||
if (result.error.graphQLErrors.length) { | ||
message = result.error.graphQLErrors | ||
.map((e) => e.originalError?.message) | ||
.join(', '); | ||
} | ||
|
||
throw new Error(message); | ||
} | ||
return result.data; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { | ||
type PublicKey, | ||
VersionedTransaction, | ||
type Cluster, | ||
clusterApiUrl, | ||
Connection, | ||
} from '@solana/web3.js'; | ||
import type { | ||
JupiterQuoteResponse, | ||
JupiterSwapResponse, | ||
Token, | ||
TokenType, | ||
} from '../types'; | ||
import { tokens } from './tokens'; | ||
|
||
const getApiUrl = () => { | ||
return process.env.JUPITER_API_URL || 'https://quote-api.jup.ag/v6'; | ||
}; | ||
|
||
export const getTransactionDetails = ( | ||
cluster: Cluster, | ||
transactionId: string, | ||
) => { | ||
const connection = new Connection(clusterApiUrl(cluster)); | ||
return connection.getParsedTransaction(transactionId, { | ||
commitment: 'confirmed', | ||
maxSupportedTransactionVersion: 0, | ||
}); | ||
}; | ||
|
||
export const getTokenList = (): Token[] => { | ||
return tokens.map((token) => ({ | ||
type: token.symbol, | ||
name: token.name, | ||
icon: token.logoURI, | ||
mintAddress: token.address, | ||
decimals: token.decimals, | ||
})); | ||
}; | ||
|
||
export const getToken = async ( | ||
token?: TokenType, | ||
): Promise<Token | undefined> => { | ||
const list = getTokenList(); | ||
return list.find((t) => t.type === token); | ||
}; | ||
|
||
export const quote = async ( | ||
sourceTokenType: TokenType, | ||
targetTokenType: TokenType, | ||
amount: number, | ||
) => { | ||
const sourceToken = await getToken(sourceTokenType); | ||
const targetToken = await getToken(targetTokenType); | ||
if (!sourceToken || !targetToken) { | ||
throw new Error('Invalid tokens'); | ||
} | ||
const newAmount = amount * 10 ** sourceToken?.decimals; | ||
const apiUrl = getApiUrl(); | ||
const quoteUrl = `${apiUrl}/quote?inputMint=${sourceToken.mintAddress}&outputMint=${targetToken.mintAddress}&amount=${newAmount}`; | ||
const quoteResponse: JupiterQuoteResponse = await fetch(quoteUrl).then( | ||
(response) => response.json(), | ||
); | ||
if ('error' in quoteResponse) { | ||
throw new Error(quoteResponse.error); | ||
} | ||
return quoteResponse; | ||
}; | ||
|
||
export const swap = async ( | ||
userAddressPubkey: PublicKey, | ||
sourceTokenType: TokenType, | ||
targetTokenType: TokenType, | ||
amount: number, | ||
) => { | ||
const quoteResponse = await quote(sourceTokenType, targetTokenType, amount); | ||
const apiUrl = getApiUrl(); | ||
const swapUrl = `${apiUrl}/swap`; | ||
const payload = { | ||
// quoteResponse from /quote api | ||
quoteResponse, | ||
// user public key to be used for the swap | ||
userPublicKey: userAddressPubkey.toString(), | ||
// auto wrap and unwrap SOL. default is true | ||
wrapAndUnwrapSol: true, | ||
// feeAccount is optional. Use if you want to charge a fee. feeBps must have been passed in /quote API. | ||
// feeAccount: "fee_account_public_key" | ||
}; | ||
const body = JSON.stringify(payload); | ||
|
||
const swapResponse: JupiterSwapResponse = await fetch(swapUrl, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body, | ||
}).then((response) => response.json()); | ||
|
||
if ('error' in swapResponse) { | ||
throw new Error(swapResponse.error); | ||
} | ||
const swapTransactionBuf = Buffer.from( | ||
swapResponse.swapTransaction, | ||
'base64', | ||
); | ||
return VersionedTransaction.deserialize(swapTransactionBuf); | ||
}; |
Oops, something went wrong.