Skip to content

Commit

Permalink
feat: Delegate upload
Browse files Browse the repository at this point in the history
  • Loading branch information
rrr523 committed Mar 21, 2024
1 parent 9e8b153 commit 7b938f0
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-maps-begin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@bnb-chain/greenfield-js-sdk': patch
---

feat: Add delegateUploadObject API
39 changes: 37 additions & 2 deletions examples/nextjs/src/components/object/create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const CreateObject = () => {
}}
/>
<br />
upload object with tx:{' '}
<button
onClick={async () => {
if (!address || !file) {
Expand Down Expand Up @@ -101,8 +102,7 @@ export const CreateObject = () => {
}}
>
1. create object tx
</button>
<br />
</button>{' '}
<button
onClick={async () => {
if (!address || !file || !txHash) return;
Expand Down Expand Up @@ -139,6 +139,41 @@ export const CreateObject = () => {
2. upload
</button>
<br />
or uploaded by delegated agent
<button
onClick={async () => {
if (!address || !file) return;

const provider = await connector?.getProvider();
const offChainData = await getOffchainAuthKeys(address, provider);
if (!offChainData) {
alert('No offchain, please create offchain pairs first');
return;
}

const uploadRes = await client.object.delegateUploadObject(
{
bucketName: createObjectInfo.bucketName,
objectName: createObjectInfo.objectName,
body: file,
},
{
type: 'EDDSA',
domain: window.location.origin,
seed: offChainData.seedString,
address,
},
);
console.log('uploadRes', uploadRes);

if (uploadRes.code === 0) {
alert('success');
}
}}
>
delegated upload
</button>
<br />
<button
onClick={async () => {
if (!address) return;
Expand Down
48 changes: 47 additions & 1 deletion packages/js-sdk/src/api/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ import {
import { GetObjectRequest } from '../types/sp/GetObject';
import { GetObjectMetaRequest, GetObjectMetaResponse } from '../types/sp/GetObjectMeta';
import { ListObjectsByBucketNameResponse } from '../types/sp/ListObjectsByBucketName';
import { PutObjectRequest } from '../types/sp/PutObject';
import { DelegatedPubObjectRequest, PutObjectRequest } from '../types/sp/PutObject';
import {
checkObjectName,
generateUrlByBucketName,
Expand All @@ -94,6 +94,11 @@ export interface IObject {

uploadObject(configParam: PutObjectRequest, authType: AuthType): Promise<SpResponse<null>>;

delegateUploadObject(
params: DelegatedPubObjectRequest,
authType: AuthType,
): Promise<SpResponse<null>>;

cancelCreateObject(msg: MsgCancelCreateObject): Promise<TxResponse>;

updateObjectInfo(msg: MsgUpdateObjectInfo): Promise<TxResponse>;
Expand Down Expand Up @@ -206,6 +211,46 @@ export class Objects implements IObject {
);
}

public async delegateUploadObject(params: DelegatedPubObjectRequest, authType: AuthType) {
const { bucketName, objectName, body, contentType = body.type, timeout = 5000 } = params;
verifyBucketName(bucketName);
verifyObjectName(objectName);
assertAuthType(authType);
let endpoint = params.endpoint;
if (!endpoint) {
endpoint = await this.sp.getSPUrlByBucket(bucketName);
}

const { reqMeta, optionsWithOutHeaders, url } = await getPutObjectMetaInfo(endpoint, {
bucketName,
objectName,
contentType,
body,
delegated: true,
});
const signHeaders = await this.spClient.signHeaders(reqMeta, authType);

try {
const result = await this.spClient.callApi(
url,
{
...optionsWithOutHeaders,
headers: signHeaders,
},
timeout,
);
const { status } = result;

return { code: 0, message: 'Put object success.', statusCode: status };
} catch (error: any) {
return {
code: -1,
message: error.message,
statusCode: error?.statusCode || NORMAL_ERROR_CODE,
};
}
}

public async uploadObject(
params: PutObjectRequest,
authType: AuthType,
Expand All @@ -226,6 +271,7 @@ export class Objects implements IObject {
contentType: body.type,
txnHash,
body,
delegated: false,
});
const signHeaders = await this.spClient.signHeaders(reqMeta, authType);

Expand Down
24 changes: 18 additions & 6 deletions packages/js-sdk/src/clients/spclient/spApis/putObject.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,43 @@
import { EMPTY_STRING_SHA256, METHOD_PUT } from '@/constants';
import { ReqMeta } from '@/types';
import { generateUrlByBucketName } from '@/utils/asserts/s3';
import { encodePath } from '../auth';
import { encodePath, getSortQueryParams } from '../auth';

// https://docs.bnbchain.org/greenfield-docs/docs/api/storage-provider-rest/put_object
export const getPutObjectMetaInfo = async (
endpoint: string,
params: {
objectName: string;
bucketName: string;
txnHash: string;
contentType: string;
body: File;
delegated?: boolean;
txnHash?: string;
},
) => {
const { bucketName, objectName, txnHash, contentType, body } = params;
const { bucketName, objectName, txnHash, contentType, body, delegated = false } = params;
const path = `/${encodePath(objectName)}`;
const query = '';
const url = new URL(path, generateUrlByBucketName(endpoint, bucketName));
let queryMap = {};

if (delegated) {
queryMap = {
delegate: '',
is_update: 'false',
payload_size: String(body.size),
visibility: '0',
};
}

let url = new URL(path, generateUrlByBucketName(endpoint, bucketName));
url = getSortQueryParams(url, queryMap);

const reqMeta: Partial<ReqMeta> = {
contentSHA256: EMPTY_STRING_SHA256,
txnHash: txnHash,
method: METHOD_PUT,
url: {
hostname: url.hostname,
query,
query: url.searchParams.toString(),
path,
},
contentType,
Expand Down
10 changes: 10 additions & 0 deletions packages/js-sdk/src/types/sp/PutObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,14 @@ export type PutObjectRequest = {
body: File;
duration?: number;
endpoint?: string;
delegated?: boolean;
};

export type DelegatedPubObjectRequest = {
bucketName: string;
objectName: string;
body: File;
endpoint?: string;
timeout?: number;
contentType?: string;
};

0 comments on commit 7b938f0

Please sign in to comment.