@nina-protocol/nina-db 0.0.103 → 0.0.105
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/models/Release.js +27 -12
- package/dist/models/Transaction.js +2 -0
- package/package.json +4 -3
- package/src/migrations/20250616215722_program_id.js +19 -0
- package/src/migrations/20250630215722_transaction_program_id.js +19 -0
- package/src/models/Release.js +26 -13
- package/src/models/Transaction.js +2 -0
package/dist/models/Release.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as anchorSerum from '@project-serum/anchor';
|
|
2
|
+
import * as anchorCoral from '@coral-xyz/anchor';
|
|
2
3
|
import { Metaplex } from '@metaplex-foundation/js';
|
|
3
4
|
import { Model } from 'objection';
|
|
4
5
|
import { stripHtmlIfNeeded, tweetNewRelease } from '../utils/index.js';
|
|
@@ -10,7 +11,7 @@ import Tag from './Tag.js';
|
|
|
10
11
|
import axios from 'axios';
|
|
11
12
|
import promiseRetry from 'promise-retry';
|
|
12
13
|
import { customAlphabet } from 'nanoid';
|
|
13
|
-
import
|
|
14
|
+
import { getTokenMetadata } from '@solana/spl-token';
|
|
14
15
|
const ensureHttps = (uri) => {
|
|
15
16
|
if (!uri.startsWith('http://') && !uri.startsWith('https://')) {
|
|
16
17
|
return `https://${uri}`;
|
|
@@ -53,21 +54,25 @@ export default class Release extends Model {
|
|
|
53
54
|
archived: { type: 'boolean' },
|
|
54
55
|
},
|
|
55
56
|
};
|
|
56
|
-
static findOrCreate = async (publicKey, hubPublicKey = null) => {
|
|
57
|
+
static findOrCreate = async (publicKey, hubPublicKey = null, programId = process.env.NINA_PROGRAM_V2_ID) => {
|
|
57
58
|
try {
|
|
59
|
+
console.log('Release.findOrCreate', publicKey, programId);
|
|
58
60
|
let release = await Release.query().findOne({ publicKey });
|
|
59
61
|
if (release) {
|
|
62
|
+
console.log('release found', release);
|
|
60
63
|
return release;
|
|
61
64
|
}
|
|
65
|
+
let anchor = programId === process.env.NINA_PROGRAM_V2_ID ? anchorCoral : anchorSerum;
|
|
62
66
|
const connection = new anchor.web3.Connection(process.env.SOLANA_CLUSTER_URL);
|
|
63
67
|
const provider = new anchor.AnchorProvider(connection, {}, { commitment: 'confirmed' });
|
|
64
|
-
const program = await anchor.Program.at(
|
|
68
|
+
const program = await anchor.Program.at(programId, provider);
|
|
69
|
+
const programModelName = programId === process.env.NINA_PROGRAM_V2_ID ? 'releaseV2' : 'release';
|
|
65
70
|
const metaplex = new Metaplex(connection);
|
|
66
71
|
let attempts = 0;
|
|
67
72
|
const releaseAccount = await promiseRetry(async (retry) => {
|
|
68
73
|
try {
|
|
69
74
|
attempts += 1;
|
|
70
|
-
const result = await program.account.
|
|
75
|
+
const result = await program.account[programModelName].fetch(new anchor.web3.PublicKey(publicKey), 'confirmed');
|
|
71
76
|
return result;
|
|
72
77
|
}
|
|
73
78
|
catch (error) {
|
|
@@ -79,7 +84,13 @@ export default class Release extends Model {
|
|
|
79
84
|
minTimeout: 500,
|
|
80
85
|
maxTimeout: 1500,
|
|
81
86
|
});
|
|
82
|
-
let metadataAccount
|
|
87
|
+
let metadataAccount;
|
|
88
|
+
if (programId === process.env.NINA_PROGRAM_V2_ID) {
|
|
89
|
+
metadataAccount = await getTokenMetadata(connection, releaseAccount.mint, 'confirmed');
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
metadataAccount = (await metaplex.nfts().findAllByMintList({ mints: [releaseAccount.releaseMint] }, { commitment: 'confirmed' }))[0];
|
|
93
|
+
}
|
|
83
94
|
if (!metadataAccount) {
|
|
84
95
|
throw new Error('No metadata account found for release - is not a complete release');
|
|
85
96
|
}
|
|
@@ -94,12 +105,13 @@ export default class Release extends Model {
|
|
|
94
105
|
let publisher = await Account.findOrCreate(releaseAccount.authority.toBase58());
|
|
95
106
|
release = await this.createRelease({
|
|
96
107
|
publicKey,
|
|
97
|
-
mint: releaseAccount.releaseMint.toBase58(),
|
|
108
|
+
mint: programId === process.env.NINA_PROGRAM_V2_ID ? releaseAccount.mint.toBase58() : releaseAccount.releaseMint.toBase58(),
|
|
98
109
|
metadata: json,
|
|
99
|
-
datetime: new Date(releaseAccount.releaseDatetime.toNumber() * 1000).toISOString(),
|
|
110
|
+
datetime: programId === process.env.NINA_PROGRAM_V2_ID ? new Date().toISOString() : new Date(releaseAccount.releaseDatetime.toNumber() * 1000).toISOString(),
|
|
100
111
|
slug,
|
|
101
112
|
publisherId: publisher.id,
|
|
102
|
-
releaseAccount
|
|
113
|
+
releaseAccount,
|
|
114
|
+
programId,
|
|
103
115
|
});
|
|
104
116
|
if (hubPublicKey) {
|
|
105
117
|
const hub = await Hub.query().findOne({ publicKey: hubPublicKey });
|
|
@@ -115,7 +127,7 @@ export default class Release extends Model {
|
|
|
115
127
|
return null;
|
|
116
128
|
}
|
|
117
129
|
};
|
|
118
|
-
static createRelease = async ({ publicKey, mint, metadata, datetime, publisherId, releaseAccount }) => {
|
|
130
|
+
static createRelease = async ({ publicKey, mint, metadata, datetime, publisherId, releaseAccount, programId }) => {
|
|
119
131
|
const slug = await this.generateSlug(metadata);
|
|
120
132
|
const price = releaseAccount.account?.price?.toNumber() || releaseAccount?.price?.toNumber() || 0;
|
|
121
133
|
const paymentMint = releaseAccount.account?.paymentMint.toBase58() || releaseAccount?.paymentMint.toBase58();
|
|
@@ -128,7 +140,8 @@ export default class Release extends Model {
|
|
|
128
140
|
publisherId,
|
|
129
141
|
price: `${price}`,
|
|
130
142
|
paymentMint,
|
|
131
|
-
archived: false
|
|
143
|
+
archived: false,
|
|
144
|
+
programId,
|
|
132
145
|
});
|
|
133
146
|
if (metadata.properties.tags) {
|
|
134
147
|
for await (let tag of metadata.properties.tags) {
|
|
@@ -136,7 +149,9 @@ export default class Release extends Model {
|
|
|
136
149
|
await Release.relatedQuery('tags').for(release.id).relate(tagRecord.id).onConflict(['tagId', 'releaseId']).ignore();
|
|
137
150
|
}
|
|
138
151
|
}
|
|
139
|
-
|
|
152
|
+
if (programId === process.env.NINA_PROGRAM_ID) {
|
|
153
|
+
await this.processRevenueShares(releaseAccount, release);
|
|
154
|
+
}
|
|
140
155
|
tweetNewRelease(metadata, publisherId, slug);
|
|
141
156
|
return release;
|
|
142
157
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nina-protocol/nina-db",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.105",
|
|
4
4
|
"description": "",
|
|
5
5
|
"source": "src/index.js",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
|
|
24
24
|
"@babel/preset-es2015": "^7.0.0-beta.53",
|
|
25
25
|
"@metaplex-foundation/js": "^0.18.1",
|
|
26
|
-
"@
|
|
26
|
+
"@coral-xyz/anchor": "^0.31.0",
|
|
27
|
+
"@solana/spl-token": "^0.4.9",
|
|
27
28
|
"axios": "^0.27.2",
|
|
28
29
|
"knex": "^2.2.0",
|
|
29
30
|
"nanoid": "^4.0.2",
|
|
@@ -46,6 +47,6 @@
|
|
|
46
47
|
"rollup-plugin-babel": "^4.4.0",
|
|
47
48
|
"rollup-plugin-commonjs": "^10.1.0",
|
|
48
49
|
"rollup-plugin-terser": "^7.0.2",
|
|
49
|
-
"typescript": "
|
|
50
|
+
"typescript": "5.7.3"
|
|
50
51
|
}
|
|
51
52
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param { import("knex").Knex } knex
|
|
3
|
+
* @returns { Promise<void> }
|
|
4
|
+
*/
|
|
5
|
+
export const up = function(knex) {
|
|
6
|
+
return knex.schema.table('releases', table => {
|
|
7
|
+
table.string('programId').notNullable().defaultTo(process.env.NINA_PROGRAM_ID);
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param { import("knex").Knex } knex
|
|
13
|
+
* @returns { Promise<void> }
|
|
14
|
+
*/
|
|
15
|
+
export const down = function(knex) {
|
|
16
|
+
return knex.schema.table('releases', table => {
|
|
17
|
+
table.dropColumn('programId');
|
|
18
|
+
});
|
|
19
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param { import("knex").Knex } knex
|
|
3
|
+
* @returns { Promise<void> }
|
|
4
|
+
*/
|
|
5
|
+
export const up = function(knex) {
|
|
6
|
+
return knex.schema.table('transactions', table => {
|
|
7
|
+
table.string('programId').notNullable().defaultTo(process.env.NINA_PROGRAM_ID);
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param { import("knex").Knex } knex
|
|
13
|
+
* @returns { Promise<void> }
|
|
14
|
+
*/
|
|
15
|
+
export const down = function(knex) {
|
|
16
|
+
return knex.schema.table('transactions', table => {
|
|
17
|
+
table.dropColumn('programId');
|
|
18
|
+
});
|
|
19
|
+
};
|
package/src/models/Release.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as anchorSerum from '@project-serum/anchor';
|
|
2
|
+
import * as anchorCoral from '@coral-xyz/anchor';
|
|
2
3
|
import { Metaplex } from '@metaplex-foundation/js';
|
|
3
4
|
import { Model } from 'objection';
|
|
4
5
|
import { stripHtmlIfNeeded, tweetNewRelease }from '../utils/index.js';
|
|
@@ -10,7 +11,7 @@ import Tag from './Tag.js';
|
|
|
10
11
|
import axios from 'axios';
|
|
11
12
|
import promiseRetry from 'promise-retry';
|
|
12
13
|
import { customAlphabet } from 'nanoid';
|
|
13
|
-
import
|
|
14
|
+
import { getTokenMetadata } from '@solana/spl-token';
|
|
14
15
|
|
|
15
16
|
const ensureHttps = (uri) => {
|
|
16
17
|
if (!uri.startsWith('http://') && !uri.startsWith('https://')) {
|
|
@@ -57,27 +58,30 @@ export default class Release extends Model {
|
|
|
57
58
|
},
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
static findOrCreate = async (publicKey, hubPublicKey=null) => {
|
|
61
|
+
static findOrCreate = async (publicKey, hubPublicKey=null, programId=process.env.NINA_PROGRAM_V2_ID) => {
|
|
61
62
|
try {
|
|
63
|
+
console.log('Release.findOrCreate', publicKey, programId)
|
|
62
64
|
let release = await Release.query().findOne({ publicKey });
|
|
63
65
|
if (release) {
|
|
66
|
+
console.log('release found', release)
|
|
64
67
|
return release;
|
|
65
68
|
}
|
|
66
69
|
|
|
70
|
+
let anchor = programId === process.env.NINA_PROGRAM_V2_ID ? anchorCoral : anchorSerum;
|
|
67
71
|
const connection = new anchor.web3.Connection(process.env.SOLANA_CLUSTER_URL);
|
|
68
72
|
const provider = new anchor.AnchorProvider(connection, {}, {commitment: 'confirmed'})
|
|
69
73
|
const program = await anchor.Program.at(
|
|
70
|
-
|
|
74
|
+
programId,
|
|
71
75
|
provider,
|
|
72
76
|
)
|
|
77
|
+
const programModelName = programId === process.env.NINA_PROGRAM_V2_ID ? 'releaseV2' : 'release';
|
|
73
78
|
const metaplex = new Metaplex(connection);
|
|
74
79
|
let attempts = 0;
|
|
75
|
-
|
|
76
80
|
const releaseAccount = await promiseRetry(
|
|
77
81
|
async (retry) => {
|
|
78
82
|
try {
|
|
79
83
|
attempts += 1
|
|
80
|
-
const result = await program.account.
|
|
84
|
+
const result = await program.account[programModelName].fetch(new anchor.web3.PublicKey(publicKey), 'confirmed')
|
|
81
85
|
return result
|
|
82
86
|
} catch (error) {
|
|
83
87
|
console.log('error fetching release account', error)
|
|
@@ -90,7 +94,12 @@ export default class Release extends Model {
|
|
|
90
94
|
}
|
|
91
95
|
)
|
|
92
96
|
|
|
93
|
-
let metadataAccount
|
|
97
|
+
let metadataAccount
|
|
98
|
+
if (programId === process.env.NINA_PROGRAM_V2_ID) {
|
|
99
|
+
metadataAccount = await getTokenMetadata(connection, releaseAccount.mint, 'confirmed')
|
|
100
|
+
} else {
|
|
101
|
+
metadataAccount = (await metaplex.nfts().findAllByMintList({mints: [releaseAccount.releaseMint]}, { commitment: 'confirmed' }))[0];
|
|
102
|
+
}
|
|
94
103
|
if (!metadataAccount) {
|
|
95
104
|
throw new Error('No metadata account found for release - is not a complete release')
|
|
96
105
|
}
|
|
@@ -105,12 +114,13 @@ export default class Release extends Model {
|
|
|
105
114
|
let publisher = await Account.findOrCreate(releaseAccount.authority.toBase58());
|
|
106
115
|
release = await this.createRelease({
|
|
107
116
|
publicKey,
|
|
108
|
-
mint: releaseAccount.releaseMint.toBase58(),
|
|
117
|
+
mint: programId === process.env.NINA_PROGRAM_V2_ID ? releaseAccount.mint.toBase58() : releaseAccount.releaseMint.toBase58(),
|
|
109
118
|
metadata: json,
|
|
110
|
-
datetime: new Date(releaseAccount.releaseDatetime.toNumber() * 1000).toISOString(),
|
|
119
|
+
datetime: programId === process.env.NINA_PROGRAM_V2_ID ? new Date().toISOString() : new Date(releaseAccount.releaseDatetime.toNumber() * 1000).toISOString(),
|
|
111
120
|
slug,
|
|
112
121
|
publisherId: publisher.id,
|
|
113
|
-
releaseAccount
|
|
122
|
+
releaseAccount,
|
|
123
|
+
programId,
|
|
114
124
|
});
|
|
115
125
|
|
|
116
126
|
if (hubPublicKey) {
|
|
@@ -129,7 +139,7 @@ export default class Release extends Model {
|
|
|
129
139
|
}
|
|
130
140
|
}
|
|
131
141
|
|
|
132
|
-
static createRelease = async ({publicKey, mint, metadata, datetime, publisherId, releaseAccount}) => {
|
|
142
|
+
static createRelease = async ({publicKey, mint, metadata, datetime, publisherId, releaseAccount, programId}) => {
|
|
133
143
|
const slug = await this.generateSlug(metadata);
|
|
134
144
|
const price = releaseAccount.account?.price?.toNumber() || releaseAccount?.price?.toNumber() || 0;
|
|
135
145
|
const paymentMint = releaseAccount.account?.paymentMint.toBase58() || releaseAccount?.paymentMint.toBase58();
|
|
@@ -142,7 +152,8 @@ export default class Release extends Model {
|
|
|
142
152
|
publisherId,
|
|
143
153
|
price: `${price}`,
|
|
144
154
|
paymentMint,
|
|
145
|
-
archived: false
|
|
155
|
+
archived: false,
|
|
156
|
+
programId,
|
|
146
157
|
})
|
|
147
158
|
if (metadata.properties.tags) {
|
|
148
159
|
for await (let tag of metadata.properties.tags) {
|
|
@@ -150,7 +161,9 @@ export default class Release extends Model {
|
|
|
150
161
|
await Release.relatedQuery('tags').for(release.id).relate(tagRecord.id).onConflict(['tagId', 'releaseId']).ignore();
|
|
151
162
|
}
|
|
152
163
|
}
|
|
153
|
-
|
|
164
|
+
if (programId === process.env.NINA_PROGRAM_ID) {
|
|
165
|
+
await this.processRevenueShares(releaseAccount, release);
|
|
166
|
+
}
|
|
154
167
|
tweetNewRelease(metadata, publisherId, slug);
|
|
155
168
|
return release;
|
|
156
169
|
}
|